Author: remy.maucherat(a)jboss.com
Date: 2012-06-14 10:11:34 -0400 (Thu, 14 Jun 2012)
New Revision: 2042
Removed:
trunk/java/org/apache/coyote/ajp/AjpProcessor.java
trunk/java/org/apache/coyote/ajp/AjpProtocol.java
trunk/java/org/apache/coyote/http11/Http11Processor.java
trunk/java/org/apache/coyote/http11/Http11Protocol.java
trunk/java/org/apache/coyote/http11/InternalInputBuffer.java
trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java
trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java
trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java
trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java
Modified:
trunk/build.properties.default
trunk/java/org/apache/catalina/connector/Connector.java
trunk/java/org/apache/coyote/http11/Http11AbstractProcessor.java
trunk/java/org/apache/tomcat/util/net/SSLImplementation.java
trunk/java/org/apache/tomcat/util/net/jsse/NioJSSEImplementation.java
trunk/webapps/docs/changelog.xml
Log:
Drop java.io connectors (AJP and HTTP). AJP now requires native.
Modified: trunk/build.properties.default
===================================================================
--- trunk/build.properties.default 2012-06-13 08:50:17 UTC (rev 2041)
+++ trunk/build.properties.default 2012-06-14 14:11:34 UTC (rev 2042)
@@ -11,7 +11,7 @@
# ----- Version Control Flags -----
version.major=7
-version.minor=0
+version.minor=7
version.build=0
version.patch=0
version.tag=SNAPSHOT
Modified: trunk/java/org/apache/catalina/connector/Connector.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Connector.java 2012-06-13 08:50:17 UTC (rev
2041)
+++ trunk/java/org/apache/catalina/connector/Connector.java 2012-06-14 14:11:34 UTC (rev
2042)
@@ -594,10 +594,7 @@
} else {
if ("HTTP/1.1".equals(protocol) ||
"http".equals(protocol)) {
setProtocolHandlerClassName
- ("org.apache.coyote.http11.Http11Protocol");
- } else if ("AJP/1.3".equals(protocol) ||
"ajp".equals(protocol)) {
- setProtocolHandlerClassName
- ("org.apache.coyote.ajp.AjpProtocol");
+ ("org.apache.coyote.http11.Http11NioProtocol");
} else if (protocol != null) {
setProtocolHandlerClassName(protocol);
}
Deleted: trunk/java/org/apache/coyote/ajp/AjpProcessor.java
===================================================================
--- trunk/java/org/apache/coyote/ajp/AjpProcessor.java 2012-06-13 08:50:17 UTC (rev 2041)
+++ trunk/java/org/apache/coyote/ajp/AjpProcessor.java 2012-06-14 14:11:34 UTC (rev 2042)
@@ -1,1350 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.apache.coyote.ajp;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.ActionHook;
-import org.apache.coyote.Adapter;
-import org.apache.coyote.InputBuffer;
-import org.apache.coyote.OutputBuffer;
-import org.apache.coyote.Request;
-import org.apache.coyote.RequestInfo;
-import org.apache.coyote.Response;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.HexUtils;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.HttpMessages;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.net.JIoEndpoint;
-import org.apache.tomcat.util.net.SocketStatus;
-import org.apache.tomcat.util.net.JIoEndpoint.Handler.SocketState;
-import org.apache.tomcat.util.res.StringManager;
-
-
-/**
- * Processes HTTP requests.
- *
- * @author Remy Maucherat
- * @author Henri Gomez
- * @author Dan Milstein
- * @author Keith Wannamaker
- * @author Kevin Seguin
- * @author Costin Manolache
- * @author Bill Barker
- */
-public class AjpProcessor implements ActionHook {
-
-
- /**
- * Logger.
- */
- protected static org.jboss.logging.Logger log
- = org.jboss.logging.Logger.getLogger(AjpProcessor.class);
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // ----------------------------------------------------------- Constructors
-
-
- public AjpProcessor(int packetSize, JIoEndpoint endpoint) {
-
- this.endpoint = endpoint;
-
- request = new Request();
- request.setInputBuffer(new SocketInputBuffer());
-
- response = new Response();
- response.setHook(this);
- response.setOutputBuffer(new SocketOutputBuffer());
- request.setResponse(response);
-
- requestHeaderMessage = new AjpMessage(packetSize);
- responseHeaderMessage = new AjpMessage(packetSize);
- bodyMessage = new AjpMessage(packetSize);
-
- // Set the get body message buffer
- AjpMessage getBodyMessage = new AjpMessage(16);
- getBodyMessage.reset();
- getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK);
- getBodyMessage.appendInt(packetSize - Constants.READ_HEAD_LEN);
- getBodyMessage.end();
- getBodyMessageArray = new byte[getBodyMessage.getLen()];
- System.arraycopy(getBodyMessage.getBuffer(), 0, getBodyMessageArray,
- 0, getBodyMessage.getLen());
-
- // Cause loading of HexUtils
- int foo = HexUtils.DEC[0];
-
- // Cause loading of HttpMessages
- HttpMessages.getMessage(200);
-
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * Associated adapter.
- */
- protected Adapter adapter = null;
-
-
- /**
- * Request object.
- */
- protected Request request = null;
-
-
- /**
- * Response object.
- */
- protected Response response = null;
-
-
- /**
- * Header message. Note that this header is merely the one used during the
- * processing of the first message of a "request", so it might not be a
request
- * header. It will stay unchanged during the processing of the whole request.
- */
- protected AjpMessage requestHeaderMessage = null;
-
-
- /**
- * Message used for response header composition.
- */
- protected AjpMessage responseHeaderMessage = null;
-
-
- /**
- * Body message.
- */
- protected AjpMessage bodyMessage = null;
-
-
- /**
- * Body message.
- */
- protected MessageBytes bodyBytes = MessageBytes.newInstance();
-
-
- /**
- * Error flag.
- */
- protected boolean error = false;
-
-
- /**
- * Socket associated with the current connection.
- */
- protected Socket socket;
-
-
- /**
- * Input stream.
- */
- protected InputStream input;
-
-
- /**
- * Output stream.
- */
- protected OutputStream output;
-
-
- /**
- * Host name (used to avoid useless B2C conversion on the host name).
- */
- protected char[] hostNameC = new char[0];
-
-
- /**
- * Associated endpoint.
- */
- protected JIoEndpoint endpoint;
-
-
- /**
- * The socket timeout used when reading the first block of the request
- * header.
- */
- protected long readTimeout;
-
-
- /**
- * Temp message bytes used for processing.
- */
- protected MessageBytes tmpMB = MessageBytes.newInstance();
-
-
- /**
- * Byte chunk for certs.
- */
- protected MessageBytes certificates = MessageBytes.newInstance();
-
-
- /**
- * End of stream flag.
- */
- protected boolean endOfStream = false;
-
-
- /**
- * Body empty flag.
- */
- protected boolean empty = true;
-
-
- /**
- * First read.
- */
- protected boolean first = true;
-
-
- /**
- * Replay read.
- */
- protected boolean replay = false;
-
-
- /**
- * Finished response.
- */
- protected boolean finished = false;
-
-
- /**
- * Direct buffer used for sending right away a get body message.
- */
- protected final byte[] getBodyMessageArray;
-
-
- /**
- * Direct buffer used for sending right away a pong message.
- */
- protected static final byte[] pongMessageArray;
-
-
- /**
- * End message array.
- */
- protected static final byte[] endMessageArray;
-
- /**
- * Flush message array.
- */
- protected static final byte[] flushMessageArray;
-
-
- /**
- * Event used.
- */
- protected boolean event = false;
-
-
- /**
- * Event processing.
- */
- protected boolean eventProcessing = true;
- public void startProcessing() { eventProcessing = true; }
- public void endProcessing() { eventProcessing = false; }
-
-
- // ----------------------------------------------------- Static Initializer
-
-
- static {
-
- // Set the read body message buffer
- AjpMessage pongMessage = new AjpMessage(16);
- pongMessage.reset();
- pongMessage.appendByte(Constants.JK_AJP13_CPONG_REPLY);
- pongMessage.end();
- pongMessageArray = new byte[pongMessage.getLen()];
- System.arraycopy(pongMessage.getBuffer(), 0, pongMessageArray,
- 0, pongMessage.getLen());
-
- // Allocate the end message array
- AjpMessage endMessage = new AjpMessage(16);
- endMessage.reset();
- endMessage.appendByte(Constants.JK_AJP13_END_RESPONSE);
- endMessage.appendByte(1);
- endMessage.end();
- endMessageArray = new byte[endMessage.getLen()];
- System.arraycopy(endMessage.getBuffer(), 0, endMessageArray, 0,
- endMessage.getLen());
-
- // Allocate the flush message array
- AjpMessage flushMessage = new AjpMessage(16);
- flushMessage.reset();
- flushMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK);
- flushMessage.appendInt(0);
- flushMessage.appendByte(0);
- flushMessage.end();
- flushMessageArray = new byte[flushMessage.getLen()];
- System.arraycopy(flushMessage.getBuffer(), 0, flushMessageArray, 0,
- flushMessage.getLen());
-
- }
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Use Tomcat authentication ?
- */
- protected boolean tomcatAuthentication = true;
- public boolean getTomcatAuthentication() { return tomcatAuthentication; }
- public void setTomcatAuthentication(boolean tomcatAuthentication) {
this.tomcatAuthentication = tomcatAuthentication; }
-
-
- /**
- * Required secret.
- */
- protected String requiredSecret = null;
- public void setRequiredSecret(String requiredSecret) { this.requiredSecret =
requiredSecret; }
-
-
- /**
- * The number of milliseconds Tomcat will wait for a subsequent request
- * before closing the connection. The default is the same as for
- * Apache HTTP Server (15 000 milliseconds).
- */
- protected int keepAliveTimeout = -1;
- public int getKeepAliveTimeout() { return keepAliveTimeout; }
- public void setKeepAliveTimeout(int timeout) { keepAliveTimeout = timeout; }
-
-
- /**
- * Timeout.
- */
- protected int timeout = -1;
- public void setTimeout(int timeout) { this.timeout = timeout; }
- public int getTimeout() { return timeout; }
-
-
- /**
- * A resume has been requested.
- */
- protected boolean resumeNotification = false;
- public boolean getResumeNotification() { return resumeNotification; }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /** Get the request associated with this processor.
- *
- * @return The request
- */
- public Request getRequest() {
- return request;
- }
-
-
- public SocketState event(SocketStatus status)
- throws IOException {
-
- RequestInfo rp = request.getRequestProcessor();
- try {
- if (status == SocketStatus.OPEN_CALLBACK) {
- // The resume notification is now done
- resumeNotification = false;
- } else if (status == SocketStatus.ERROR) {
- // Set error flag right away
- error = true;
- }
- rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
- error = !adapter.event(request, response, status);
- } catch (InterruptedIOException e) {
- error = true;
- } catch (Throwable t) {
- log.error(sm.getString("http11processor.request.process"), t);
- // 500 - Internal Server Error
- response.setStatus(500);
- error = true;
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-
- if (error) {
- recycle();
- return SocketState.CLOSED;
- } else if (!event) {
- finish();
- recycle();
- return SocketState.OPEN;
- } else {
- return SocketState.LONG;
- }
- }
-
-
- /**
- * Process pipelined HTTP requests using the specified input and output
- * streams.
- *
- * @throws IOException error during an I/O operation
- */
- public SocketState process(Socket socket)
- throws IOException {
- RequestInfo rp = request.getRequestProcessor();
- rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
-
- // Setting up the socket
- this.socket = socket;
- input = socket.getInputStream();
- output = socket.getOutputStream();
- int soTimeout = -1;
- if (keepAliveTimeout > 0) {
- soTimeout = socket.getSoTimeout();
- }
-
- // Error flag
- error = false;
-
- while (!error && !event) {
-
- // Parsing the request header
- try {
- // Set keep alive timeout if enabled
- if (keepAliveTimeout > 0) {
- socket.setSoTimeout(keepAliveTimeout);
- }
- // Get first message of the request
- if (!readMessage(requestHeaderMessage)) {
- // This means a connection timeout
- rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
- break;
- }
- // Set back timeout if keep alive timeout is enabled
- if (keepAliveTimeout > 0) {
- socket.setSoTimeout(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) {
- try {
- output.write(pongMessageArray);
- } catch (IOException e) {
- error = true;
- }
- continue;
- } else if(type != Constants.JK_AJP13_FORWARD_REQUEST) {
- // Usually the servlet didn't read the previous request body
- if(log.isDebugEnabled()) {
- log.debug("Unexpected message: "+type);
- }
- error = true;
- break;
- }
-
- request.setStartTime(System.currentTimeMillis());
- } catch (IOException e) {
- error = true;
- break;
- } catch (Throwable t) {
- log.debug(sm.getString("ajpprocessor.header.error"), t);
- // 400 - Bad Request
- response.setStatus(400);
- error = true;
- }
-
- // Setting up filters, and parse some request headers
- rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
- try {
- prepareRequest();
- } catch (Throwable t) {
- log.debug(sm.getString("ajpprocessor.request.prepare"), t);
- // 400 - Internal Server Error
- response.setStatus(400);
- error = true;
- }
-
- // 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) {
- log.error(sm.getString("ajpprocessor.request.process"),
t);
- // 500 - Internal Server Error
- response.setStatus(500);
- error = true;
- }
- }
-
- // Finish the response if not done yet
- if (!event && !finished) {
- try {
- finish();
- } catch (Throwable 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();
-
- if (!event) {
- recycle();
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
-
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-
- if (event) {
- if (error) {
- input = null;
- output = null;
- recycle();
- return SocketState.CLOSED;
- } else {
- eventProcessing = false;
- return SocketState.LONG;
- }
- } else {
- input = null;
- output = null;
- recycle();
- return SocketState.CLOSED;
- }
- }
-
-
- // ----------------------------------------------------- ActionHook Methods
-
-
- /**
- * Send an action to the connector.
- *
- * @param actionCode Type of the action
- * @param param Action parameter
- */
- public void action(ActionCode actionCode, Object param) {
-
- if (actionCode == ActionCode.ACTION_COMMIT) {
-
- if (response.isCommitted())
- return;
-
- // Validate and write response headers
- try {
- prepareResponse();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) {
-
- if (!response.isCommitted()) {
- // Validate and write response headers
- try {
- prepareResponse();
- } catch (IOException e) {
- // Set error flag
- error = true;
- return;
- }
- }
-
- try {
- flush();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_CLOSE) {
- // Close
-
- // End the processing of the current request, and stop any further
- // transactions with the client
-
- try {
- finish();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) {
-
- if (!certificates.isNull()) {
- ByteChunk certData = certificates.getByteChunk();
- X509Certificate jsseCerts[] = null;
- ByteArrayInputStream bais =
- new ByteArrayInputStream(certData.getBytes(),
- certData.getStart(),
- certData.getLength());
- // Fill the elements.
- try {
- CertificateFactory cf =
- CertificateFactory.getInstance("X.509");
- while(bais.available() > 0) {
- X509Certificate cert = (X509Certificate)
- cf.generateCertificate(bais);
- if(jsseCerts == null) {
- jsseCerts = new X509Certificate[1];
- jsseCerts[0] = cert;
- } else {
- X509Certificate [] temp = new
X509Certificate[jsseCerts.length+1];
- System.arraycopy(jsseCerts,0,temp,0,jsseCerts.length);
- temp[jsseCerts.length] = cert;
- jsseCerts = temp;
- }
- }
- } catch (java.security.cert.CertificateException e) {
- log.error(sm.getString("ajpprocessor.certs.fail"), e);
- return;
- }
-
request.setAttribute(org.apache.tomcat.util.net.Constants.CERTIFICATE_KEY, jsseCerts);
- }
-
- } else if (actionCode == ActionCode.ACTION_REQ_HOST_ATTRIBUTE) {
-
- // Get remote host name using a DNS resolution
- if (request.remoteHost().isNull()) {
- try {
- request.remoteHost().setString(InetAddress.getByName
- (request.remoteAddr().toString()).getHostName());
- } catch (IOException iex) {
- // Ignore
- }
- }
-
- } else if (actionCode == ActionCode.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE) {
-
- // Copy from local name for now, which should simply be an address
- request.localAddr().setString(request.localName().toString());
-
- } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) {
-
- // Set the given bytes as the content
- ByteChunk bc = (ByteChunk) param;
- int length = bc.getLength();
- bodyBytes.setBytes(bc.getBytes(), bc.getStart(), length);
- request.setContentLength(length);
- first = false;
- empty = false;
- replay = true;
- endOfStream = false;
-
- } else if (actionCode == ActionCode.ACTION_EVENT_BEGIN) {
- event = true;
- } else if (actionCode == ActionCode.ACTION_EVENT_END) {
- event = false;
- } else if (actionCode == ActionCode.ACTION_EVENT_SUSPEND) {
- // No action needed
- } else if (actionCode == ActionCode.ACTION_EVENT_RESUME) {
- // An event is being processed already: adding for resume will be done
- // when the socket gets back to the poller
- if (!eventProcessing && !resumeNotification) {
- endpoint.getEventPoller().add(socket, timeout, true, true);
- }
- resumeNotification = true;
- } else if (actionCode == ActionCode.ACTION_EVENT_TIMEOUT) {
- timeout = ((Integer) param).intValue();
- }
-
-
- }
-
-
- // ------------------------------------------------------ Connector Methods
-
-
- /**
- * Set the associated adapter.
- *
- * @param adapter the new adapter
- */
- public void setAdapter(Adapter adapter) {
- this.adapter = adapter;
- }
-
-
- /**
- * Get the associated adapter.
- *
- * @return the associated adapter
- */
- public Adapter getAdapter() {
- return adapter;
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * After reading the request headers, we have to setup the request filters.
- */
- protected void prepareRequest() {
-
- // Translate the HTTP method code to a String.
- byte methodCode = requestHeaderMessage.getByte();
- if (methodCode != Constants.SC_M_JK_STORED) {
- String methodName = Constants.methodTransArray[(int)methodCode - 1];
- request.method().setString(methodName);
- }
-
- requestHeaderMessage.getBytes(request.protocol());
- requestHeaderMessage.getBytes(request.requestURI());
-
- requestHeaderMessage.getBytes(request.remoteAddr());
- requestHeaderMessage.getBytes(request.remoteHost());
- requestHeaderMessage.getBytes(request.localName());
- request.setLocalPort(requestHeaderMessage.getInt());
-
- boolean isSSL = requestHeaderMessage.getByte() != 0;
- if (isSSL) {
- request.scheme().setString("https");
- }
-
- // Decode headers
- MimeHeaders headers = request.getMimeHeaders();
-
- int hCount = requestHeaderMessage.getInt();
- for(int i = 0 ; i < hCount ; i++) {
- String hName = null;
-
- // Header names are encoded as either an integer code starting
- // with 0xA0, or as a normal string (in which case the first
- // two bytes are the length).
- int isc = requestHeaderMessage.peekInt();
- int hId = isc & 0xFF;
-
- MessageBytes vMB = null;
- isc &= 0xFF00;
- if(0xA000 == isc) {
- requestHeaderMessage.getInt(); // To advance the read position
- hName = Constants.headerTransArray[hId - 1];
- vMB = headers.addValue(hName);
- } else {
- // reset hId -- if the header currently being read
- // happens to be 7 or 8 bytes long, the code below
- // will think it's the content-type header or the
- // content-length header - SC_REQ_CONTENT_TYPE=7,
- // SC_REQ_CONTENT_LENGTH=8 - leading to unexpected
- // behaviour. see bug 5861 for more information.
- hId = -1;
- requestHeaderMessage.getBytes(tmpMB);
- ByteChunk bc = tmpMB.getByteChunk();
- vMB = headers.addValue(bc.getBuffer(),
- bc.getStart(), bc.getLength());
- }
-
- requestHeaderMessage.getBytes(vMB);
-
- if (hId == Constants.SC_REQ_CONTENT_LENGTH ||
- (hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Length"))) {
- // just read the content-length header, so set it
- request.setContentLength( vMB.getInt() );
- } else if (hId == Constants.SC_REQ_CONTENT_TYPE ||
- (hId == -1 &&
tmpMB.equalsIgnoreCase("Content-Type"))) {
- // just read the content-type header, so set it
- ByteChunk bchunk = vMB.getByteChunk();
- request.contentType().setBytes(bchunk.getBytes(),
- bchunk.getOffset(),
- bchunk.getLength());
- }
- }
-
- // Decode extra attributes
- boolean secret = false;
- byte attributeCode;
- while ((attributeCode = requestHeaderMessage.getByte())
- != Constants.SC_A_ARE_DONE) {
-
- switch (attributeCode) {
-
- case Constants.SC_A_REQ_ATTRIBUTE :
- requestHeaderMessage.getBytes(tmpMB);
- String n = tmpMB.toString();
- requestHeaderMessage.getBytes(tmpMB);
- String v = tmpMB.toString();
- request.setAttribute(n, v);
- break;
-
- case Constants.SC_A_CONTEXT :
- requestHeaderMessage.getBytes(tmpMB);
- // nothing
- break;
-
- case Constants.SC_A_SERVLET_PATH :
- requestHeaderMessage.getBytes(tmpMB);
- // nothing
- break;
-
- case Constants.SC_A_REMOTE_USER :
- if (tomcatAuthentication) {
- // ignore server
- requestHeaderMessage.getBytes(tmpMB);
- } else {
- requestHeaderMessage.getBytes(request.getRemoteUser());
- }
- break;
-
- case Constants.SC_A_AUTH_TYPE :
- if (tomcatAuthentication) {
- // ignore server
- requestHeaderMessage.getBytes(tmpMB);
- } else {
- requestHeaderMessage.getBytes(request.getAuthType());
- }
- break;
-
- case Constants.SC_A_QUERY_STRING :
- requestHeaderMessage.getBytes(request.queryString());
- break;
-
- case Constants.SC_A_JVM_ROUTE :
- requestHeaderMessage.getBytes(request.instanceId());
- break;
-
- case Constants.SC_A_SSL_CERT :
- request.scheme().setString("https");
- // SSL certificate extraction is lazy, moved to JkCoyoteHandler
- requestHeaderMessage.getBytes(certificates);
- break;
-
- case Constants.SC_A_SSL_CIPHER :
- request.scheme().setString("https");
- requestHeaderMessage.getBytes(tmpMB);
-
request.setAttribute(org.apache.tomcat.util.net.Constants.CIPHER_SUITE_KEY,
- tmpMB.toString());
- break;
-
- case Constants.SC_A_SSL_SESSION :
- request.scheme().setString("https");
- requestHeaderMessage.getBytes(tmpMB);
-
request.setAttribute(org.apache.tomcat.util.net.Constants.SESSION_ID_KEY,
- tmpMB.toString());
- break;
-
- case Constants.SC_A_SSL_KEY_SIZE :
- request.setAttribute(org.apache.tomcat.util.net.Constants.KEY_SIZE_KEY,
- new Integer(requestHeaderMessage.getInt()));
- break;
-
- case Constants.SC_A_STORED_METHOD:
- requestHeaderMessage.getBytes(request.method());
- break;
-
- case Constants.SC_A_SECRET:
- requestHeaderMessage.getBytes(tmpMB);
- if (requiredSecret != null) {
- secret = true;
- if (!tmpMB.equals(requiredSecret)) {
- response.setStatus(403);
- error = true;
- }
- }
- break;
-
- default:
- // Ignore unknown attribute for backward compatibility
- break;
-
- }
-
- }
-
- // Check if secret was submitted if required
- if ((requiredSecret != null) && !secret) {
- response.setStatus(403);
- error = true;
- }
-
- // Check for a full URI (including protocol://host:port/)
- ByteChunk uriBC = request.requestURI().getByteChunk();
- if (uriBC.startsWithIgnoreCase("http", 0)) {
-
- int pos = uriBC.indexOf("://", 0, 3, 4);
- int uriBCStart = uriBC.getStart();
- int slashPos = -1;
- if (pos != -1) {
- byte[] uriB = uriBC.getBytes();
- slashPos = uriBC.indexOf('/', pos + 3);
- if (slashPos == -1) {
- slashPos = uriBC.getLength();
- // Set URI as "/"
- request.requestURI().setBytes
- (uriB, uriBCStart + pos + 1, 1);
- } else {
- request.requestURI().setBytes
- (uriB, uriBCStart + slashPos,
- uriBC.getLength() - slashPos);
- }
- MessageBytes hostMB = headers.setValue("host");
- hostMB.setBytes(uriB, uriBCStart + pos + 3,
- slashPos - pos - 3);
- }
-
- }
-
- MessageBytes valueMB = request.getMimeHeaders().getValue("host");
- parseHost(valueMB);
-
- }
-
-
- /**
- * Parse host.
- */
- public void parseHost(MessageBytes valueMB) {
-
- if (valueMB == null || (valueMB != null && valueMB.isNull()) ) {
- // HTTP/1.0
- request.setServerPort(request.getLocalPort());
- try {
- request.serverName().duplicate(request.localName());
- } catch (IOException e) {
- response.setStatus(400);
- error = true;
- }
- return;
- }
-
- ByteChunk valueBC = valueMB.getByteChunk();
- byte[] valueB = valueBC.getBytes();
- int valueL = valueBC.getLength();
- int valueS = valueBC.getStart();
- int colonPos = -1;
- if (hostNameC.length < valueL) {
- hostNameC = new char[valueL];
- }
-
- boolean ipv6 = (valueB[valueS] == '[');
- boolean bracketClosed = false;
- for (int i = 0; i < valueL; i++) {
- char b = (char) valueB[i + valueS];
- hostNameC[i] = b;
- if (b == ']') {
- bracketClosed = true;
- } else if (b == ':') {
- if (!ipv6 || bracketClosed) {
- colonPos = i;
- break;
- }
- }
- }
-
- if (colonPos < 0) {
- if (request.scheme().equalsIgnoreCase("https")) {
- // 443 - Default HTTPS port
- request.setServerPort(443);
- } else {
- // 80 - Default HTTTP port
- request.setServerPort(80);
- }
- request.serverName().setChars(hostNameC, 0, valueL);
- } else {
-
- request.serverName().setChars(hostNameC, 0, colonPos);
-
- int port = 0;
- int mult = 1;
- for (int i = valueL - 1; i > colonPos; i--) {
- int charValue = HexUtils.DEC[(int) valueB[i + valueS]];
- if (charValue == -1) {
- // Invalid character
- error = true;
- // 400 - Bad request
- response.setStatus(400);
- break;
- }
- port = port + (charValue * mult);
- mult = 10 * mult;
- }
- request.setServerPort(port);
-
- }
-
- }
-
-
- /**
- * When committing the response, we have to validate the set of headers, as
- * well as setup the response filters.
- */
- protected void prepareResponse()
- throws IOException {
-
- response.setCommitted(true);
-
- responseHeaderMessage.reset();
- responseHeaderMessage.appendByte(Constants.JK_AJP13_SEND_HEADERS);
-
- // HTTP header contents
- responseHeaderMessage.appendInt(response.getStatus());
- String message = null;
- if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
- message = response.getMessage();
- }
- if (message == null){
- message = HttpMessages.getMessage(response.getStatus());
- } else {
- message = message.replace('\n', ' ').replace('\r',
' ');
- }
- if (message == null) {
- // Many httpd 2.x wants a non empty status message
- message = Integer.toString(response.getStatus());
- }
- tmpMB.setString(message);
- responseHeaderMessage.appendBytes(tmpMB);
-
- // Special headers
- MimeHeaders headers = response.getMimeHeaders();
- String contentType = response.getContentType();
- if (contentType != null) {
- headers.setValue("Content-Type").setString(contentType);
- }
- String contentLanguage = response.getContentLanguage();
- if (contentLanguage != null) {
- headers.setValue("Content-Language").setString(contentLanguage);
- }
- int contentLength = response.getContentLength();
- if (contentLength >= 0) {
- headers.setValue("Content-Length").setInt(contentLength);
- }
-
- // Other headers
- int numHeaders = headers.size();
- responseHeaderMessage.appendInt(numHeaders);
- for (int i = 0; i < numHeaders; i++) {
- MessageBytes hN = headers.getName(i);
- MessageBytes hV=headers.getValue(i);
- if (hN.getLength() > 0 && !hV.isNull()) {
- int hC = Constants.getResponseAjpIndex(hN.toString());
- if (hC > 0) {
- responseHeaderMessage.appendInt(hC);
- }
- else {
- responseHeaderMessage.appendBytes(hN);
- }
- responseHeaderMessage.appendBytes(hV);
- }
- }
-
- // Write to buffer
- responseHeaderMessage.end();
- output.write(responseHeaderMessage.getBuffer(), 0,
responseHeaderMessage.getLen());
-
- }
-
-
- /**
- * Finish AJP response.
- */
- protected void finish()
- throws IOException {
-
- if (!response.isCommitted()) {
- // Validate and write response headers
- try {
- prepareResponse();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
- }
-
- if (finished)
- return;
-
- finished = true;
-
- // Add the end message
- output.write(endMessageArray);
-
-
- // read remaining data from the special first-body-chunk
- if (first && request.getContentLengthLong() > 0) {
- try {
- receive();
- } catch (IOException e) {
- }
- }
-
- }
-
-
- /**
- * Read at least the specified amount of bytes, and place them
- * in the input buffer.
- */
- protected boolean read(byte[] buf, int pos, int n)
- throws IOException {
-
- int read = 0;
- int res = 0;
- while (read < n) {
- res = input.read(buf, read + pos, n - read);
- if (res > 0) {
- read += res;
- } else {
- throw new IOException(sm.getString("ajpprotocol.failedread"));
- }
- }
-
- return true;
-
- }
-
-
- /** Receive a chunk of data. Called to implement the
- * 'special' packet in ajp13 and to receive the data
- * after we send a GET_BODY packet
- */
- public boolean receive() throws IOException {
-
- first = false;
- bodyMessage.reset();
- readMessage(bodyMessage);
-
- // No data received.
- if (bodyMessage.getLen() == 0) {
- // just the header
- // Don't mark 'end of stream' for the first chunk.
- return false;
- }
- int blen = bodyMessage.peekInt();
- if (blen == 0) {
- return false;
- }
-
- bodyMessage.getBytes(bodyBytes);
- empty = false;
- return true;
- }
-
- /**
- * Get more request body data from the web server and store it in the
- * internal buffer.
- *
- * @return true if there is more data, false if not.
- */
- private boolean refillReadBuffer() throws IOException {
- // If the server returns an empty packet, assume that that end of
- // the stream has been reached (yuck -- fix protocol??).
- // FORM support
- if (replay) {
- endOfStream = true; // we've read everything there is
- }
- if (endOfStream) {
- return false;
- }
- if (finished) {
- return false;
- }
-
- // Request more data immediately
- output.write(getBodyMessageArray);
-
- boolean moreData = receive();
- if( !moreData ) {
- endOfStream = true;
- }
- return moreData;
- }
-
-
- /**
- * Read an AJP message.
- *
- * @return true if the message has been read, false if the short read
- * didn't return anything
- * @throws IOException any other failure, including incomplete reads
- */
- protected boolean readMessage(AjpMessage message)
- throws IOException {
-
- byte[] buf = message.getBuffer();
-
- read(buf, 0, message.getHeaderLength());
-
- if (message.processHeader() < 0) {
- throw new IOException(sm.getString("ajpprotocol.badmessage"));
- }
- read(buf, message.getHeaderLength(), message.getLen());
-
- return true;
-
- }
-
-
- /**
- * Recycle the processor.
- */
- public void recycle() {
-
- // Recycle Request object
- first = true;
- endOfStream = false;
- empty = true;
- replay = false;
- finished = false;
- timeout = -1;
- resumeNotification = false;
- eventProcessing = true;
- request.recycle();
- response.recycle();
- certificates.recycle();
-
- }
-
-
- /**
- * Callback to write data from the buffer.
- */
- protected void flush()
- throws IOException {
- // Send the flush message
- output.write(flushMessageArray);
- }
-
-
- // ------------------------------------- InputStreamInputBuffer Inner Class
-
-
- /**
- * This class is an input buffer which will read its data from an input
- * stream.
- */
- protected class SocketInputBuffer
- implements InputBuffer {
-
-
- /**
- * Read bytes into the specified chunk.
- */
- public int doRead(ByteChunk chunk, Request req )
- throws IOException {
-
- if (endOfStream) {
- return -1;
- }
- if (first && req.getContentLength() > 0) {
- // Handle special first-body-chunk
- if (!receive()) {
- return 0;
- }
- } else if (empty) {
- if (!refillReadBuffer()) {
- return -1;
- }
- }
- ByteChunk bc = bodyBytes.getByteChunk();
- chunk.setBytes(bc.getBuffer(), bc.getStart(), bc.getLength());
- empty = true;
- return chunk.getLength();
-
- }
-
- }
-
-
- // ----------------------------------- OutputStreamOutputBuffer Inner Class
-
-
- /**
- * This class is an output buffer which will write data to an output
- * stream.
- */
- protected class SocketOutputBuffer
- implements OutputBuffer {
-
-
- /**
- * Write chunk.
- */
- public int doWrite(ByteChunk chunk, Response res)
- throws IOException {
-
- if (!response.isCommitted()) {
- // Validate and write response headers
- try {
- prepareResponse();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
- }
-
- int len = chunk.getLength();
- // 4 - hardcoded, byte[] marshalling overhead
- int chunkSize = Constants.MAX_SEND_SIZE;
- int off = 0;
- while (len > 0) {
- int thisTime = len;
- if (thisTime > chunkSize) {
- thisTime = chunkSize;
- }
- len -= thisTime;
- responseHeaderMessage.reset();
- responseHeaderMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK);
- responseHeaderMessage.appendBytes(chunk.getBytes(), chunk.getOffset() +
off, thisTime);
- responseHeaderMessage.end();
- output.write(responseHeaderMessage.getBuffer(), 0,
responseHeaderMessage.getLen());
-
- off += thisTime;
- }
-
- return chunk.getLength();
-
- }
-
-
- }
-
-
-}
Deleted: trunk/java/org/apache/coyote/ajp/AjpProtocol.java
===================================================================
--- trunk/java/org/apache/coyote/ajp/AjpProtocol.java 2012-06-13 08:50:17 UTC (rev 2041)
+++ trunk/java/org/apache/coyote/ajp/AjpProtocol.java 2012-06-14 14:11:34 UTC (rev 2042)
@@ -1,577 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.apache.coyote.ajp;
-
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URLEncoder;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.coyote.Adapter;
-import org.apache.coyote.ProtocolHandler;
-import org.apache.coyote.RequestGroupInfo;
-import org.apache.coyote.RequestInfo;
-import org.apache.tomcat.util.modeler.Registry;
-import org.apache.tomcat.util.net.JIoEndpoint;
-import org.apache.tomcat.util.net.SocketStatus;
-import org.apache.tomcat.util.net.JIoEndpoint.Handler;
-import org.apache.tomcat.util.res.StringManager;
-
-
-/**
- * Abstract the protocol implementation, including threading, etc.
- * Processor is single threaded and specific to stream-based protocols,
- * will not fit Jk protocols like JNI.
- *
- * @author Remy Maucherat
- * @author Costin Manolache
- */
-public class AjpProtocol
- implements ProtocolHandler, MBeanRegistration {
-
-
- protected static org.jboss.logging.Logger log =
- org.jboss.logging.Logger.getLogger(AjpProtocol.class);
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // ------------------------------------------------------------ Constructor
-
-
- public AjpProtocol() {
- cHandler = new AjpConnectionHandler(this);
- setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
- setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
- //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT);
- setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- protected ObjectName tpOname;
-
-
- protected ObjectName rgOname;
-
-
- /**
- * Associated java.io endpoint.
- */
- protected JIoEndpoint endpoint = new JIoEndpoint();
-
-
- /**
- * Configuration attributes.
- */
- protected Hashtable attributes = new Hashtable();
-
-
- /**
- * Adapter which will process the requests recieved by this endpoint.
- */
- private Adapter adapter;
-
-
- /**
- * Connection handler for AJP.
- */
- private AjpConnectionHandler cHandler;
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Pass config info
- */
- public void setAttribute(String name, Object value) {
- if (log.isTraceEnabled()) {
- log.trace(sm.getString("ajpprotocol.setattribute", name, value));
- }
- attributes.put(name, value);
- }
-
- public Object getAttribute(String key) {
- if (log.isTraceEnabled()) {
- log.trace(sm.getString("ajpprotocol.getattribute", key));
- }
- return attributes.get(key);
- }
-
-
- public Iterator getAttributeNames() {
- return attributes.keySet().iterator();
- }
-
-
- /**
- * The adapter, used to call the connector
- */
- public void setAdapter(Adapter adapter) {
- this.adapter = adapter;
- }
-
-
- public Adapter getAdapter() {
- return adapter;
- }
-
-
- public boolean hasIoEvents() {
- return false;
- }
-
- public RequestGroupInfo getRequestGroupInfo() {
- return cHandler.global;
- }
-
-
- /** Start the protocol
- */
- public void init() throws Exception {
- endpoint.setName(getName());
- endpoint.setHandler(cHandler);
-
- try {
- endpoint.init();
- } catch (Exception ex) {
- log.error(sm.getString("ajpprotocol.endpoint.initerror"), ex);
- throw ex;
- }
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("ajpprotocol.init", getName()));
- }
- }
-
-
- public void start() throws Exception {
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER) {
- if (this.domain != null ) {
- try {
- tpOname = new ObjectName
- (domain + ":" + "type=ThreadPool,name=" +
getName());
- Registry.getRegistry(null, null)
- .registerComponent(endpoint, tpOname, null );
- } catch (Exception e) {
- log.error("Can't register threadpool" );
- }
- rgOname = new ObjectName
- (domain + ":type=GlobalRequestProcessor,name=" + getName());
- Registry.getRegistry(null, null).registerComponent
- (cHandler.global, rgOname, null);
- }
- }
- try {
- endpoint.start();
- } catch (Exception ex) {
- log.error(sm.getString("ajpprotocol.endpoint.starterror"), ex);
- throw ex;
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("ajpprotocol.start", getName()));
- }
-
- public void pause() throws Exception {
- try {
- endpoint.pause();
- } catch (Exception ex) {
- log.error(sm.getString("ajpprotocol.endpoint.pauseerror"), ex);
- throw ex;
- }
- // Wait for a while until all the processors are idle
- RequestInfo[] states = cHandler.global.getRequestProcessors();
- int retry = 0;
- boolean done = false;
- while (!done && retry < org.apache.coyote.Constants.MAX_PAUSE_WAIT) {
- retry++;
- done = true;
- for (int i = 0; i < states.length; i++) {
- if (states[i].getStage() == org.apache.coyote.Constants.STAGE_SERVICE) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- ;
- }
- done = false;
- break;
- }
- }
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("ajpprotocol.pause", getName()));
- }
-
- public void resume() throws Exception {
- try {
- endpoint.resume();
- } catch (Exception ex) {
- log.error(sm.getString("ajpprotocol.endpoint.resumeerror"), ex);
- throw ex;
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("ajpprotocol.resume", getName()));
- }
-
- public void destroy() throws Exception {
- if (log.isInfoEnabled())
- log.info(sm.getString("ajpprotocol.stop", getName()));
- endpoint.destroy();
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER) {
- if (tpOname!=null)
- Registry.getRegistry(null, null).unregisterComponent(tpOname);
- if (rgOname != null)
- Registry.getRegistry(null, null).unregisterComponent(rgOname);
- }
- }
-
- public String getJmxName() {
- String encodedAddr = "";
- if (getAddress() != null) {
- encodedAddr = "" + getAddress();
- encodedAddr = URLEncoder.encode(encodedAddr.replace('/',
'-').replace(':', '_').replace('%', '-')) +
"-";
- }
- return ("ajp-" + encodedAddr + endpoint.getPort());
- }
-
- public String getName() {
- String encodedAddr = "";
- if (getAddress() != null) {
- encodedAddr = getAddress() + ":";
- }
- return ("ajp-" + encodedAddr + endpoint.getPort());
- }
-
- /**
- * Processor cache.
- */
- protected int processorCache = -1;
- public int getProcessorCache() { return this.processorCache; }
- public void setProcessorCache(int processorCache) { this.processorCache =
processorCache; }
-
- public Executor getExecutor() { return endpoint.getExecutor(); }
- public void setExecutor(Executor executor) { endpoint.setExecutor(executor); }
-
- public int getMaxThreads() { return endpoint.getMaxThreads(); }
- public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); }
-
- public int getThreadPriority() { return endpoint.getThreadPriority(); }
- public void setThreadPriority(int threadPriority) {
endpoint.setThreadPriority(threadPriority); }
-
- public int getBacklog() { return endpoint.getBacklog(); }
- public void setBacklog(int backlog) { endpoint.setBacklog(backlog); }
-
- public int getPort() { return endpoint.getPort(); }
- public void setPort(int port) { endpoint.setPort(port); }
-
- public InetAddress getAddress() { return endpoint.getAddress(); }
- public void setAddress(InetAddress ia) { endpoint.setAddress(ia); }
-
- public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); }
- public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay);
}
-
- public int getSoLinger() { return endpoint.getSoLinger(); }
- public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); }
-
- public int getSoTimeout() { return endpoint.getSoTimeout(); }
- public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); }
-
- public void setPollerSize(int pollerSize) { endpoint.setPollerSize(pollerSize); }
- public int getPollerSize() { return endpoint.getPollerSize(); }
-
- /**
- * Should authentication be done in the native webserver layer,
- * or in the Servlet container ?
- */
- protected boolean tomcatAuthentication = true;
- public boolean getTomcatAuthentication() { return tomcatAuthentication; }
- public void setTomcatAuthentication(boolean tomcatAuthentication) {
this.tomcatAuthentication = tomcatAuthentication; }
-
- /**
- * Required secret.
- */
- protected String requiredSecret = null;
- public void setRequiredSecret(String requiredSecret) { this.requiredSecret =
requiredSecret; }
-
- /**
- * AJP packet size.
- */
- protected int packetSize = Constants.MAX_PACKET_SIZE;
- public int getPacketSize() { return packetSize; }
- public void setPacketSize(int packetSize) { this.packetSize = packetSize; }
-
-
- /**
- * The number of seconds Tomcat will wait for a subsequent request
- * before closing the connection.
- */
- protected int keepAliveTimeout = -1;
- public int getKeepAliveTimeout() { return keepAliveTimeout; }
- public void setKeepAliveTimeout(int timeout) { keepAliveTimeout = timeout; }
-
-
- // -------------------------------------- AjpConnectionHandler Inner Class
-
-
- protected static class AjpConnectionHandler implements Handler {
-
- protected AjpProtocol proto;
- protected AtomicLong registerCount = new AtomicLong(0);
- protected RequestGroupInfo global = new RequestGroupInfo();
-
- protected ConcurrentHashMap<Socket, AjpProcessor> connections =
- new ConcurrentHashMap<Socket, AjpProcessor>();
- protected ConcurrentLinkedQueue<AjpProcessor> recycledProcessors =
- new ConcurrentLinkedQueue<AjpProcessor>() {
- protected AtomicInteger size = new AtomicInteger(0);
- public boolean offer(AjpProcessor processor) {
- boolean offer = (proto.processorCache == -1) ? true : (size.get() <
proto.processorCache);
- //avoid over growing our cache or add after we have stopped
- boolean result = false;
- if ( offer ) {
- result = super.offer(processor);
- if ( result ) {
- size.incrementAndGet();
- }
- }
- if (!result) unregister(processor);
- return result;
- }
-
- public AjpProcessor poll() {
- AjpProcessor result = super.poll();
- if ( result != null ) {
- size.decrementAndGet();
- }
- return result;
- }
-
- public void clear() {
- AjpProcessor next = poll();
- while ( next != null ) {
- unregister(next);
- next = poll();
- }
- super.clear();
- size.set(0);
- }
- };
-
- public AjpConnectionHandler(AjpProtocol proto) {
- this.proto = proto;
- }
-
- public SocketState event(Socket socket, SocketStatus status) {
- AjpProcessor result = connections.get(socket);
- SocketState state = SocketState.CLOSED;
- if (result != null) {
- result.startProcessing();
- // Call the appropriate event
- try {
- state = result.event(status);
- } catch (java.net.SocketException e) {
- // SocketExceptions are normal
- AjpProcessor.log.debug
- (sm.getString
- ("ajpprotocol.proto.socketexception.debug"), e);
- } catch (java.io.IOException e) {
- // IOExceptions are normal
- AjpProcessor.log.debug
- (sm.getString
- ("ajpprotocol.proto.ioexception.debug"), e);
- }
- // Future developers: if you discover any other
- // rare-but-nonfatal exceptions, catch them here, and log as
- // above.
- catch (Throwable e) {
- // any other exception or error is odd. Here we log it
- // with "ERROR" level, so it will show up even on
- // less-than-verbose logs.
- AjpProcessor.log.error
- (sm.getString("ajpprotocol.proto.error"), e);
- } finally {
- if (state != SocketState.LONG) {
- connections.remove(socket);
- recycledProcessors.offer(result);
- } else {
- if (proto.endpoint.isRunning()) {
- proto.endpoint.getEventPoller().add(socket,
result.getTimeout(),
- result.getResumeNotification(), false);
- }
- }
- result.endProcessing();
- }
- }
- return state;
- }
-
- public SocketState process(Socket socket) {
- AjpProcessor processor = recycledProcessors.poll();
- try {
-
- if (processor == null) {
- processor = createProcessor();
- }
-
- SocketState state = processor.process(socket);
- if (state == SocketState.LONG) {
- // Associate the connection with the processor. The next request
- // processed by this thread will use either a new or a recycled
- // processor.
- connections.put(socket, processor);
- proto.endpoint.getEventPoller().add(socket, processor.getTimeout(),
- processor.getResumeNotification(), false);
- } else {
- recycledProcessors.offer(processor);
- }
- return state;
-
- } catch(java.net.SocketException e) {
- // SocketExceptions are normal
- AjpProtocol.log.debug
- (sm.getString
- ("ajpprotocol.proto.socketexception.debug"), e);
- } catch (java.io.IOException e) {
- // IOExceptions are normal
- AjpProtocol.log.debug
- (sm.getString
- ("ajpprotocol.proto.ioexception.debug"), e);
- }
- // Future developers: if you discover any other
- // rare-but-nonfatal exceptions, catch them here, and log as
- // above.
- catch (Throwable e) {
- // any other exception or error is odd. Here we log it
- // with "ERROR" level, so it will show up even on
- // less-than-verbose logs.
- AjpProtocol.log.error
- (sm.getString("ajpprotocol.proto.error"), e);
- }
- recycledProcessors.offer(processor);
- return SocketState.CLOSED;
- }
-
- protected AjpProcessor createProcessor() {
- AjpProcessor processor = new AjpProcessor(proto.packetSize, proto.endpoint);
- processor.setAdapter(proto.adapter);
- processor.setTomcatAuthentication(proto.tomcatAuthentication);
- processor.setRequiredSecret(proto.requiredSecret);
- processor.setKeepAliveTimeout(proto.keepAliveTimeout);
- register(processor);
- return processor;
- }
-
- protected void register(AjpProcessor processor) {
- RequestInfo rp = processor.getRequest().getRequestProcessor();
- rp.setGlobalProcessor(global);
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER &&
proto.getDomain() != null) {
- synchronized (this) {
- try {
- long count = registerCount.incrementAndGet();
- ObjectName rpName = new ObjectName
- (proto.getDomain() +
":type=RequestProcessor,worker="
- + proto.getJmxName() + ",name=AjpRequest" +
count);
- if (log.isDebugEnabled()) {
- log.debug("Register " + rpName);
- }
- Registry.getRegistry(null, null).registerComponent(rp, rpName,
null);
- rp.setRpName(rpName);
- } catch (Exception e) {
- log.warn("Error registering request");
- }
- }
- }
- }
-
- protected void unregister(AjpProcessor processor) {
- RequestInfo rp = processor.getRequest().getRequestProcessor();
- rp.setGlobalProcessor(null);
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER &&
proto.getDomain() != null) {
- synchronized (this) {
- try {
- ObjectName rpName = rp.getRpName();
- if (log.isDebugEnabled()) {
- log.debug("Unregister " + rpName);
- }
- Registry.getRegistry(null, null).unregisterComponent(rpName);
- rp.setRpName(null);
- } catch (Exception e) {
- log.warn("Error unregistering request", e);
- }
- }
- }
- }
-
- }
-
-
- // -------------------- Various implementation classes --------------------
-
-
- protected String domain;
- protected ObjectName oname;
- protected MBeanServer mserver;
-
- public ObjectName getObjectName() {
- return oname;
- }
-
- public String getDomain() {
- return domain;
- }
-
- public ObjectName preRegister(MBeanServer server,
- ObjectName name) throws Exception {
- oname=name;
- mserver=server;
- domain=name.getDomain();
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
-
- public void postDeregister() {
- }
-
-
-}
Modified: trunk/java/org/apache/coyote/http11/Http11AbstractProcessor.java
===================================================================
--- trunk/java/org/apache/coyote/http11/Http11AbstractProcessor.java 2012-06-13 08:50:17
UTC (rev 2041)
+++ trunk/java/org/apache/coyote/http11/Http11AbstractProcessor.java 2012-06-14 14:11:34
UTC (rev 2042)
@@ -51,7 +51,7 @@
* Logger.
*/
protected static org.jboss.logging.Logger log = org.jboss.logging.Logger
- .getLogger(Http11Processor.class);
+ .getLogger(Http11AbstractProcessor.class);
/**
* The string manager for this package.
Deleted: trunk/java/org/apache/coyote/http11/Http11Processor.java
===================================================================
--- trunk/java/org/apache/coyote/http11/Http11Processor.java 2012-06-13 08:50:17 UTC (rev
2041)
+++ trunk/java/org/apache/coyote/http11/Http11Processor.java 2012-06-14 14:11:34 UTC (rev
2042)
@@ -1,1745 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.apache.coyote.http11;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.Locale;
-import java.util.StringTokenizer;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.ActionHook;
-import org.apache.coyote.Adapter;
-import org.apache.coyote.Request;
-import org.apache.coyote.RequestInfo;
-import org.apache.coyote.Response;
-import org.apache.coyote.http11.filters.BufferedInputFilter;
-import org.apache.coyote.http11.filters.ChunkedInputFilter;
-import org.apache.coyote.http11.filters.ChunkedOutputFilter;
-import org.apache.coyote.http11.filters.GzipOutputFilter;
-import org.apache.coyote.http11.filters.IdentityInputFilter;
-import org.apache.coyote.http11.filters.IdentityOutputFilter;
-import org.apache.coyote.http11.filters.SavedRequestInputFilter;
-import org.apache.coyote.http11.filters.VoidInputFilter;
-import org.apache.coyote.http11.filters.VoidOutputFilter;
-import org.apache.tomcat.util.buf.Ascii;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.HexUtils;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.FastHttpDateFormat;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.net.JIoEndpoint;
-import org.apache.tomcat.util.net.SSLSupport;
-import org.apache.tomcat.util.net.SocketStatus;
-import org.apache.tomcat.util.net.JIoEndpoint.Handler.SocketState;
-import org.apache.tomcat.util.res.StringManager;
-
-
-/**
- * Processes HTTP requests.
- *
- * @author Remy Maucherat
- */
-public class Http11Processor implements ActionHook {
-
-
- /**
- * Logger.
- */
- protected static org.jboss.logging.Logger log
- = org.jboss.logging.Logger.getLogger(Http11Processor.class);
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- protected static final boolean CHUNK_ON_CLOSE =
-
Boolean.valueOf(System.getProperty("org.apache.coyote.http11.Http11Processor.CHUNK_ON_CLOSE",
"false")).booleanValue();
-
-
- // ------------------------------------------------------------ Constructor
-
-
- public Http11Processor(int headerBufferSize, JIoEndpoint endpoint) {
-
- this.endpoint = endpoint;
-
- request = new Request();
- inputBuffer = new InternalInputBuffer(request, headerBufferSize);
- request.setInputBuffer(inputBuffer);
-
- response = new Response();
- response.setHook(this);
- outputBuffer = new InternalOutputBuffer(response, headerBufferSize);
- response.setOutputBuffer(outputBuffer);
- request.setResponse(response);
-
- initializeFilters();
-
- // Cause loading of HexUtils
- int foo = HexUtils.DEC[0];
-
- // Cause loading of FastHttpDateFormat
- FastHttpDateFormat.getCurrentDate();
-
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * Associated adapter.
- */
- protected Adapter adapter = null;
-
-
- /**
- * Request object.
- */
- protected Request request = null;
-
-
- /**
- * Response object.
- */
- protected Response response = null;
-
-
- /**
- * Input.
- */
- protected InternalInputBuffer inputBuffer = null;
-
-
- /**
- * Output.
- */
- protected InternalOutputBuffer outputBuffer = null;
-
-
- /**
- * Error flag.
- */
- protected boolean error = false;
-
-
- /**
- * Keep-alive.
- */
- protected boolean keepAlive = true;
-
-
- /**
- * HTTP/1.1 flag.
- */
- protected boolean http11 = true;
-
-
- /**
- * HTTP/0.9 flag.
- */
- protected boolean http09 = false;
-
-
- /**
- * Content delimitator for the request (if false, the connection will
- * be closed at the end of the request).
- */
- protected boolean contentDelimitation = true;
-
-
- /**
- * Is there an expectation ?
- */
- protected boolean expectation = false;
-
-
- /**
- * List of restricted user agents.
- */
- protected Pattern[] restrictedUserAgents = null;
-
-
- /**
- * Maximum number of Keep-Alive requests to honor.
- */
- protected int maxKeepAliveRequests = -1;
-
- /**
- * The number of seconds Tomcat will wait for a subsequent request
- * before closing the connection.
- */
- protected int keepAliveTimeout = -1;
-
-
- /**
- * SSL information.
- */
- protected SSLSupport sslSupport;
-
-
- /**
- * Socket associated with the current connection.
- */
- protected Socket socket;
-
-
- /**
- * Remote Address associated with the current connection.
- */
- protected String remoteAddr = null;
-
-
- /**
- * Remote Host associated with the current connection.
- */
- protected String remoteHost = null;
-
-
- /**
- * Local Host associated with the current connection.
- */
- protected String localName = null;
-
-
-
- /**
- * Local port to which the socket is connected
- */
- protected int localPort = -1;
-
-
- /**
- * Remote port to which the socket is connected
- */
- protected int remotePort = -1;
-
-
- /**
- * The local Host address.
- */
- protected String localAddr = null;
-
-
- /**
- * Flag to disable setting a different time-out on uploads.
- */
- protected boolean disableUploadTimeout = false;
-
-
- /**
- * Allowed compression level.
- */
- protected int compressionLevel = 0;
-
-
- /**
- * Minimum contentsize to make compression.
- */
- protected int compressionMinSize = 2048;
-
-
- /**
- * Socket buffering.
- */
- protected int socketBuffer = -1;
-
-
- /**
- * Max saved post size.
- */
- protected int maxSavePostSize = 4 * 1024;
-
-
- /**
- * List of user agents to not use gzip with
- */
- protected Pattern noCompressionUserAgents[] = null;
-
- /**
- * List of MIMES which could be gzipped
- */
- protected String[] compressableMimeTypes =
- { "text/html", "text/xml", "text/plain" };
-
-
- /**
- * Host name (used to avoid useless B2C conversion on the host name).
- */
- protected char[] hostNameC = new char[0];
-
-
- /**
- * Associated endpoint.
- */
- protected JIoEndpoint endpoint;
-
-
- /**
- * Allow a customized the server header for the tin-foil hat folks.
- */
- protected String server = null;
-
-
- /**
- * Event used.
- */
- protected boolean event = false;
-
-
- /**
- * True if a resume has been requested.
- */
- protected boolean resumeNotification = false;
-
-
- /**
- * Event processing.
- */
- protected boolean eventProcessing = true;
- public void startProcessing() { eventProcessing = true; }
- public void endProcessing() { eventProcessing = false; }
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Return compression level.
- */
- public String getCompression() {
- switch (compressionLevel) {
- case 0:
- return "off";
- case 1:
- return "on";
- case 2:
- return "force";
- }
- return "off";
- }
-
-
- /**
- * Set compression level.
- */
- public void setCompression(String compression) {
- if (compression.equals("on")) {
- this.compressionLevel = 1;
- } else if (compression.equals("force")) {
- this.compressionLevel = 2;
- } else if (compression.equals("off")) {
- this.compressionLevel = 0;
- } else {
- try {
- // Try to parse compression as an int, which would give the
- // minimum compression size
- compressionMinSize = Integer.parseInt(compression);
- this.compressionLevel = 1;
- } catch (Exception e) {
- this.compressionLevel = 0;
- }
- }
- }
-
- /**
- * Set Minimum size to trigger compression.
- */
- public void setCompressionMinSize(int compressionMinSize) {
- this.compressionMinSize = compressionMinSize;
- }
-
-
- /**
- * Add user-agent for which gzip compression didn't works
- * The user agent String given will be exactly matched
- * to the user-agent header submitted by the client.
- *
- * @param userAgent user-agent string
- */
- public void addNoCompressionUserAgent(String userAgent) {
- try {
- Pattern nRule = Pattern.compile(userAgent);
- noCompressionUserAgents =
- addREArray(noCompressionUserAgents, nRule);
- } catch (PatternSyntaxException pse) {
- log.error(sm.getString("http11processor.regexp.error", userAgent),
pse);
- }
- }
-
-
- /**
- * Set no compression user agent list (this method is best when used with
- * a large number of connectors, where it would be better to have all of
- * them referenced a single array).
- */
- public void setNoCompressionUserAgents(Pattern[] noCompressionUserAgents) {
- this.noCompressionUserAgents = noCompressionUserAgents;
- }
-
-
- /**
- * Set no compression user agent list.
- * List contains users agents separated by ',' :
- *
- * ie: "gorilla,desesplorer,tigrus"
- */
- public void setNoCompressionUserAgents(String noCompressionUserAgents) {
- if (noCompressionUserAgents != null) {
- StringTokenizer st = new StringTokenizer(noCompressionUserAgents,
",");
-
- while (st.hasMoreTokens()) {
- addNoCompressionUserAgent(st.nextToken().trim());
- }
- }
- }
-
- /**
- * Add a mime-type which will be compressable
- * The mime-type String will be exactly matched
- * in the response mime-type header .
- *
- * @param mimeType mime-type string
- */
- public void addCompressableMimeType(String mimeType) {
- compressableMimeTypes =
- addStringArray(compressableMimeTypes, mimeType);
- }
-
-
- /**
- * Set compressable mime-type list (this method is best when used with
- * a large number of connectors, where it would be better to have all of
- * them referenced a single array).
- */
- public void setCompressableMimeTypes(String[] compressableMimeTypes) {
- this.compressableMimeTypes = compressableMimeTypes;
- }
-
-
- /**
- * Set compressable mime-type list
- * List contains users agents separated by ',' :
- *
- * ie: "text/html,text/xml,text/plain"
- */
- public void setCompressableMimeTypes(String compressableMimeTypes) {
- if (compressableMimeTypes != null) {
- this.compressableMimeTypes = null;
- StringTokenizer st = new StringTokenizer(compressableMimeTypes,
",");
- while (st.hasMoreTokens()) {
- addCompressableMimeType(st.nextToken().trim());
- }
- }
- }
-
-
- /**
- * Return the list of restricted user agents.
- */
- public String[] findCompressableMimeTypes() {
- return (compressableMimeTypes);
- }
-
-
- /**
- * Timeout.
- */
- protected int timeout = -1;
- public void setTimeout(int timeout) { this.timeout = timeout; }
- public int getTimeout() { return timeout; }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Add input or output filter.
- *
- * @param className class name of the filter
- */
- protected void addFilter(String className) {
- try {
- Class<?> clazz = Class.forName(className);
- Object obj = clazz.newInstance();
- if (obj instanceof InputFilter) {
- inputBuffer.addFilter((InputFilter) obj);
- } else if (obj instanceof OutputFilter) {
- outputBuffer.addFilter((OutputFilter) obj);
- } else {
- log.warn(sm.getString("http11processor.filter.unknown",
className));
- }
- } catch (Exception e) {
- log.error(sm.getString("http11processor.filter.error", className),
e);
- }
- }
-
-
- /**
- * General use method
- *
- * @param sArray the StringArray
- * @param value string
- */
- private String[] addStringArray(String sArray[], String value) {
- String[] result = null;
- if (sArray == null) {
- result = new String[1];
- result[0] = value;
- }
- else {
- result = new String[sArray.length + 1];
- for (int i = 0; i < sArray.length; i++)
- result[i] = sArray[i];
- result[sArray.length] = value;
- }
- return result;
- }
-
-
- /**
- * General use method
- *
- * @param rArray the REArray
- * @param value Obj
- */
- private Pattern[] addREArray(Pattern rArray[], Pattern value) {
- Pattern[] result = null;
- if (rArray == null) {
- result = new Pattern[1];
- result[0] = value;
- }
- else {
- result = new Pattern[rArray.length + 1];
- for (int i = 0; i < rArray.length; i++)
- result[i] = rArray[i];
- result[rArray.length] = value;
- }
- return result;
- }
-
-
- /**
- * Checks if any entry in the string array starts with the specified value
- *
- * @param sArray the StringArray
- * @param value string
- */
- private boolean startsWithStringArray(String sArray[], String value) {
- if (value == null)
- return false;
- for (int i = 0; i < sArray.length; i++) {
- if (value.startsWith(sArray[i])) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
- * Add restricted user-agent (which will downgrade the connector
- * to HTTP/1.0 mode). The user agent String given will be matched
- * via regexp to the user-agent header submitted by the client.
- *
- * @param userAgent user-agent string
- */
- public void addRestrictedUserAgent(String userAgent) {
- try {
- Pattern nRule = Pattern.compile(userAgent);
- restrictedUserAgents = addREArray(restrictedUserAgents, nRule);
- } catch (PatternSyntaxException pse) {
- log.error(sm.getString("http11processor.regexp.error", userAgent),
pse);
- }
- }
-
-
- /**
- * Set restricted user agent list (this method is best when used with
- * a large number of connectors, where it would be better to have all of
- * them referenced a single array).
- */
- public void setRestrictedUserAgents(Pattern[] restrictedUserAgents) {
- this.restrictedUserAgents = restrictedUserAgents;
- }
-
-
- /**
- * Set restricted user agent list (which will downgrade the connector
- * to HTTP/1.0 mode). List contains users agents separated by ',' :
- *
- * ie: "gorilla,desesplorer,tigrus"
- */
- public void setRestrictedUserAgents(String restrictedUserAgents) {
- if (restrictedUserAgents != null) {
- StringTokenizer st =
- new StringTokenizer(restrictedUserAgents, ",");
- while (st.hasMoreTokens()) {
- addRestrictedUserAgent(st.nextToken().trim());
- }
- }
- }
-
-
- /**
- * Return the list of restricted user agents.
- */
- public String[] findRestrictedUserAgents() {
- String[] sarr = new String [restrictedUserAgents.length];
-
- for (int i = 0; i < restrictedUserAgents.length; i++)
- sarr[i] = restrictedUserAgents[i].toString();
-
- return (sarr);
- }
-
-
- /**
- * Set the maximum number of Keep-Alive requests to honor.
- * This is to safeguard from DoS attacks. Setting to a negative
- * value disables the check.
- */
- public void setMaxKeepAliveRequests(int mkar) {
- maxKeepAliveRequests = mkar;
- }
-
-
- /**
- * Return the number of Keep-Alive requests that we will honor.
- */
- public int getMaxKeepAliveRequests() {
- return maxKeepAliveRequests;
- }
-
- /**
- * Set the Keep-Alive timeout.
- */
- public void setKeepAliveTimeout(int timeout) {
- keepAliveTimeout = timeout;
- }
-
-
- /**
- * Return the number Keep-Alive timeout.
- */
- public int getKeepAliveTimeout() {
- return keepAliveTimeout;
- }
-
-
- /**
- * Set the maximum size of a POST which will be buffered in SSL mode.
- */
- public void setMaxSavePostSize(int msps) {
- maxSavePostSize = msps;
- }
-
-
- /**
- * Return the maximum size of a POST which will be buffered in SSL mode.
- */
- public int getMaxSavePostSize() {
- return maxSavePostSize;
- }
-
-
- /**
- * Set the SSL information for this HTTP connection.
- */
- public void setSSLSupport(SSLSupport sslSupport) {
- this.sslSupport = sslSupport;
- }
-
-
- /**
- * Set the flag to control upload time-outs.
- */
- public void setDisableUploadTimeout(boolean isDisabled) {
- disableUploadTimeout = isDisabled;
- }
-
- /**
- * Get the flag that controls upload time-outs.
- */
- public boolean getDisableUploadTimeout() {
- return disableUploadTimeout;
- }
-
- public boolean getResumeNotification() {
- return resumeNotification;
- }
-
-
- /**
- * Set the socket buffer flag.
- */
- public void setSocketBuffer(int socketBuffer) {
- this.socketBuffer = socketBuffer;
- outputBuffer.setSocketBuffer(socketBuffer);
- }
-
- /**
- * Get the socket buffer flag.
- */
- public int getSocketBuffer() {
- return socketBuffer;
- }
-
-
- /**
- * Set the server header name.
- */
- public void setServer( String server ) {
- if (server==null || server.equals("")) {
- this.server = null;
- } else {
- this.server = server;
- }
- }
-
- /**
- * Get the server header name.
- */
- public String getServer() {
- return server;
- }
-
-
- /** Get the request associated with this processor.
- *
- * @return The request
- */
- public Request getRequest() {
- return request;
- }
-
- public SocketState event(SocketStatus status)
- throws IOException {
-
- RequestInfo rp = request.getRequestProcessor();
- try {
- if (status == SocketStatus.OPEN_CALLBACK) {
- // The resume notification is now done
- resumeNotification = false;
- } else if (status == SocketStatus.ERROR) {
- // Set error flag right away
- error = true;
- }
- rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
- error = !adapter.event(request, response, status);
- } catch (InterruptedIOException e) {
- error = true;
- } catch (Throwable t) {
- log.error(sm.getString("http11processor.request.process"), t);
- // 500 - Internal Server Error
- response.setStatus(500);
- error = true;
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-
- if (error) {
- inputBuffer.nextRequest();
- outputBuffer.nextRequest();
- recycle();
- return SocketState.CLOSED;
- } else if (!event) {
- endRequest();
- boolean pipelined = inputBuffer.nextRequest();
- outputBuffer.nextRequest();
- recycle();
- return (pipelined || !keepAlive) ? SocketState.CLOSED : SocketState.OPEN;
- } else {
- return SocketState.LONG;
- }
- }
-
- /**
- * Process pipelined HTTP requests on the specified socket.
- *
- * @param socket Socket from which the HTTP requests will be read
- * and the HTTP responses will be written.
- *
- * @throws IOException error during an I/O operation
- */
- public SocketState process(Socket socket)
- throws IOException {
- RequestInfo rp = request.getRequestProcessor();
- rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
-
- // Set the remote address
- remoteAddr = null;
- remoteHost = null;
- localAddr = null;
- localName = null;
- remotePort = -1;
- localPort = -1;
-
- // Setting up the I/O
- this.socket = socket;
- inputBuffer.setInputStream(socket.getInputStream());
- outputBuffer.setOutputStream(socket.getOutputStream());
-
- // Error flag
- error = false;
- keepAlive = true;
-
- int keepAliveLeft = maxKeepAliveRequests;
- int soTimeout = socket.getSoTimeout();
-
- int threadRatio = (endpoint.getCurrentThreadsBusy() * 100)
- / endpoint.getMaxThreads();
- if (threadRatio > 75) {
- keepAliveLeft = 1;
- }
-
- boolean keptAlive = false;
-
- while (!error && keepAlive && !event) {
-
- // Parsing the request header
- try {
- if (!disableUploadTimeout && keptAlive) {
- if (keepAliveTimeout > 0) {
- socket.setSoTimeout(keepAliveTimeout);
- }
- else if (soTimeout > 0) {
- socket.setSoTimeout(soTimeout);
- }
- }
- inputBuffer.parseRequestLine();
- request.setStartTime(System.currentTimeMillis());
- keptAlive = true;
- if (!disableUploadTimeout) {
- socket.setSoTimeout(timeout);
- }
- inputBuffer.parseHeaders();
- } catch (IOException e) {
- error = true;
- break;
- } catch (Throwable t) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.header.parse"),
t);
- }
- // 400 - Bad Request
- response.setStatus(400);
- error = true;
- }
-
- // Setting up filters, and parse some request headers
- rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
- try {
- prepareRequest();
- } catch (Throwable t) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.request.prepare"),
t);
- }
- // 400 - Internal Server Error
- response.setStatus(400);
- error = true;
- }
-
- if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
- keepAlive = false;
-
- // Process the request in the adapter
- if (!error) {
- try {
- rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
- adapter.service(request, response);
- // Handle when the response was committed before a serious
- // error occurred. Throwing a ServletException should both
- // set the status to 500 and set the errorException.
- // If we fail here, then the response is likely already
- // committed, so we can't try and set headers.
- if(keepAlive && !error) { // Avoid checking twice.
- error = response.getErrorException() != null ||
- statusDropsConnection(response.getStatus());
- }
-
- } catch (InterruptedIOException e) {
- error = true;
- } catch (Throwable t) {
- log.error(sm.getString("http11processor.request.process"),
t);
- // 500 - Internal Server Error
- response.setStatus(500);
- error = true;
- }
- }
-
- // Finish the handling of the request
- if (error) {
- // If there is an unspecified error, the connection will be closed
- inputBuffer.setSwallowInput(false);
- }
- if (!event) {
- endRequest();
- }
-
- // 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();
-
- if (!event) {
- // Next request
- inputBuffer.nextRequest();
- outputBuffer.nextRequest();
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
-
- }
-
- rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-
- if (event) {
- if (error) {
- inputBuffer.nextRequest();
- outputBuffer.nextRequest();
- recycle();
- return SocketState.CLOSED;
- } else {
- eventProcessing = false;
- return SocketState.LONG;
- }
- } else {
- recycle();
- return SocketState.CLOSED;
- }
-
- }
-
-
- public void endRequest() {
-
- // Finish the handling of the request
- try {
- inputBuffer.endRequest();
- } catch (IOException e) {
- error = true;
- } catch (Throwable t) {
- log.error(sm.getString("http11processor.request.finish"), t);
- // 500 - Internal Server Error
- response.setStatus(500);
- error = true;
- }
- try {
- outputBuffer.endRequest();
- } catch (IOException e) {
- error = true;
- } catch (Throwable t) {
- log.error(sm.getString("http11processor.response.finish"), t);
- error = true;
- }
-
- }
-
-
- public void recycle() {
- inputBuffer.recycle();
- outputBuffer.recycle();
- this.socket = null;
- sslSupport = null;
- timeout = -1;
- resumeNotification = false;
- eventProcessing = true;
- }
-
-
- // ----------------------------------------------------- ActionHook Methods
-
-
- /**
- * Send an action to the connector.
- *
- * @param actionCode Type of the action
- * @param param Action parameter
- */
- public void action(ActionCode actionCode, Object param) {
-
- if (actionCode == ActionCode.ACTION_COMMIT) {
- // Commit current response
-
- if (response.isCommitted())
- return;
-
- // Validate and write response headers
- prepareResponse();
- try {
- outputBuffer.commit();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_ACK) {
-
- // Acknowlege request
-
- // Send a 100 status back if it makes sense (response not committed
- // yet, and client specified an expectation for 100-continue)
-
- if ((response.isCommitted()) || !expectation)
- return;
-
- inputBuffer.setSwallowInput(true);
- try {
- outputBuffer.sendAck();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) {
-
- try {
- outputBuffer.flush();
- } catch (IOException e) {
- // Set error flag
- error = true;
- response.setErrorException(e);
- }
-
- } else if (actionCode == ActionCode.ACTION_CLOSE) {
- // Close
-
- // End the processing of the current request, and stop any further
- // transactions with the client
-
- try {
- outputBuffer.endRequest();
- } catch (IOException e) {
- // Set error flag
- error = true;
- }
-
- } else if (actionCode == ActionCode.ACTION_CUSTOM) {
-
- // Do nothing
-
- } else if (actionCode == ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) {
-
- try {
- if (sslSupport != null) {
- Object sslO = sslSupport.getCipherSuite();
- if (sslO != null)
-
request.setAttribute(org.apache.tomcat.util.net.Constants.CIPHER_SUITE_KEY, sslO);
- sslO = sslSupport.getPeerCertificateChain(false);
- if (sslO != null)
-
request.setAttribute(org.apache.tomcat.util.net.Constants.CERTIFICATE_KEY, sslO);
- sslO = sslSupport.getKeySize();
- if (sslO != null)
-
request.setAttribute(org.apache.tomcat.util.net.Constants.KEY_SIZE_KEY, sslO);
- sslO = sslSupport.getSessionId();
- if (sslO != null)
-
request.setAttribute(org.apache.tomcat.util.net.Constants.SESSION_ID_KEY, sslO);
- }
- } catch (Exception e) {
- log.warn(sm.getString("http11processor.socket.ssl"), e);
- }
-
- } else if (actionCode == ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE) {
-
- if ((remoteAddr == null) && (socket != null)) {
- InetAddress inetAddr = socket.getInetAddress();
- if (inetAddr != null) {
- remoteAddr = inetAddr.getHostAddress();
- }
- }
- request.remoteAddr().setString(remoteAddr);
-
- } else if (actionCode == ActionCode.ACTION_REQ_LOCAL_NAME_ATTRIBUTE) {
-
- if ((localName == null) && (socket != null)) {
- InetAddress inetAddr = socket.getLocalAddress();
- if (inetAddr != null) {
- localName = inetAddr.getHostName();
- }
- }
- request.localName().setString(localName);
-
- } else if (actionCode == ActionCode.ACTION_REQ_HOST_ATTRIBUTE) {
-
- if ((remoteHost == null) && (socket != null)) {
- InetAddress inetAddr = socket.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.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE) {
-
- if (localAddr == null)
- localAddr = socket.getLocalAddress().getHostAddress();
-
- request.localAddr().setString(localAddr);
-
- } else if (actionCode == ActionCode.ACTION_REQ_REMOTEPORT_ATTRIBUTE) {
-
- if ((remotePort == -1 ) && (socket !=null)) {
- remotePort = socket.getPort();
- }
- request.setRemotePort(remotePort);
-
- } else if (actionCode == ActionCode.ACTION_REQ_LOCALPORT_ATTRIBUTE) {
-
- if ((localPort == -1 ) && (socket !=null)) {
- localPort = socket.getLocalPort();
- }
- request.setLocalPort(localPort);
-
- } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) {
- if( sslSupport != null) {
- // Consume and buffer the request body, so that it does not
- // interfere with the client's handshake messages
- if (maxSavePostSize != 0) {
- BufferedInputFilter buffredInputFilter = new BufferedInputFilter();
- buffredInputFilter.setLimit(maxSavePostSize);
- inputBuffer.addActiveFilter(buffredInputFilter);
- }
- try {
- Object sslO = sslSupport.getPeerCertificateChain(true);
- if (sslO != null) {
-
request.setAttribute(org.apache.tomcat.util.net.Constants.CERTIFICATE_KEY, sslO);
- }
- } catch (Exception e) {
- log.warn(sm.getString("http11processor.socket.ssl"), e);
- }
- }
- } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) {
- ByteChunk body = (ByteChunk) param;
-
- InputFilter savedBody = new SavedRequestInputFilter(body);
- savedBody.setRequest(request);
-
- InternalInputBuffer internalBuffer = (InternalInputBuffer)
- request.getInputBuffer();
- internalBuffer.addActiveFilter(savedBody);
- } else if (actionCode == ActionCode.ACTION_EVENT_BEGIN) {
- event = true;
- } else if (actionCode == ActionCode.ACTION_EVENT_END) {
- event = false;
- } else if (actionCode == ActionCode.ACTION_EVENT_SUSPEND) {
- // No action needed
- } else if (actionCode == ActionCode.ACTION_EVENT_RESUME) {
- // An event is being processed already: adding for resume will be done
- // when the socket gets back to the poller
- if (!eventProcessing && !resumeNotification) {
- endpoint.getEventPoller().add(socket, timeout, true, true);
- }
- resumeNotification = true;
- } else if (actionCode == ActionCode.ACTION_EVENT_TIMEOUT) {
- timeout = ((Integer) param).intValue();
- }
-
- }
-
-
- // ------------------------------------------------------ Connector Methods
-
-
- /**
- * Set the associated adapter.
- *
- * @param adapter the new adapter
- */
- public void setAdapter(Adapter adapter) {
- this.adapter = adapter;
- }
-
-
- /**
- * Get the associated adapter.
- *
- * @return the associated adapter
- */
- public Adapter getAdapter() {
- return adapter;
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * After reading the request headers, we have to setup the request filters.
- */
- protected void prepareRequest() {
-
- http11 = true;
- http09 = false;
- contentDelimitation = false;
- expectation = false;
- if (sslSupport != null) {
- request.scheme().setString("https");
- }
- MessageBytes protocolMB = request.protocol();
- if (protocolMB.equals(Constants.HTTP_11)) {
- http11 = true;
- protocolMB.setString(Constants.HTTP_11);
- } else if (protocolMB.equals(Constants.HTTP_10)) {
- http11 = false;
- keepAlive = false;
- protocolMB.setString(Constants.HTTP_10);
- } else if (protocolMB.equals("")) {
- // HTTP/0.9
- http09 = true;
- http11 = false;
- keepAlive = false;
- } else {
- // Unsupported protocol
- http11 = false;
- error = true;
- // Send 505; Unsupported HTTP version
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.request.prepare")+
- " Unsupported HTTP version
\""+protocolMB+"\"");
- }
- response.setStatus(505);
- }
-
- MessageBytes methodMB = request.method();
- if (methodMB.equals(Constants.GET)) {
- methodMB.setString(Constants.GET);
- } else if (methodMB.equals(Constants.POST)) {
- methodMB.setString(Constants.POST);
- }
-
- MimeHeaders headers = request.getMimeHeaders();
-
- // Check connection header
- MessageBytes connectionValueMB = headers.getValue("connection");
- if (connectionValueMB != null) {
- ByteChunk connectionValueBC = connectionValueMB.getByteChunk();
- if (findBytes(connectionValueBC, Constants.CLOSE_BYTES) != -1) {
- keepAlive = false;
- } else if (findBytes(connectionValueBC,
- Constants.KEEPALIVE_BYTES) != -1) {
- keepAlive = true;
- }
- }
-
- MessageBytes expectMB = null;
- if (http11)
- expectMB = headers.getValue("expect");
- if ((expectMB != null)
- && (expectMB.indexOfIgnoreCase("100-continue", 0) != -1))
{
- inputBuffer.setSwallowInput(false);
- expectation = true;
- }
-
- // Check user-agent header
- if ((restrictedUserAgents != null) && ((http11) || (keepAlive))) {
- MessageBytes userAgentValueMB = headers.getValue("user-agent");
- // Check in the restricted list, and adjust the http11
- // and keepAlive flags accordingly
- if(userAgentValueMB != null) {
- String userAgentValue = userAgentValueMB.toString();
- for (int i = 0; i < restrictedUserAgents.length; i++) {
- if (restrictedUserAgents[i].matcher(userAgentValue).matches()) {
- http11 = false;
- keepAlive = false;
- break;
- }
- }
- }
- }
-
- // Check for a full URI (including protocol://host:port/)
- ByteChunk uriBC = request.requestURI().getByteChunk();
- if (uriBC.startsWithIgnoreCase("http", 0)) {
-
- int pos = uriBC.indexOf("://", 0, 3, 4);
- int uriBCStart = uriBC.getStart();
- int slashPos = -1;
- if (pos != -1) {
- byte[] uriB = uriBC.getBytes();
- slashPos = uriBC.indexOf('/', pos + 3);
- if (slashPos == -1) {
- slashPos = uriBC.getLength();
- // Set URI as "/"
- request.requestURI().setBytes
- (uriB, uriBCStart + pos + 1, 1);
- } else {
- request.requestURI().setBytes
- (uriB, uriBCStart + slashPos,
- uriBC.getLength() - slashPos);
- }
- MessageBytes hostMB = headers.setValue("host");
- hostMB.setBytes(uriB, uriBCStart + pos + 3,
- slashPos - pos - 3);
- }
-
- }
-
- // Input filter setup
- InputFilter[] inputFilters = inputBuffer.getFilters();
-
- // Parse transfer-encoding header
- MessageBytes transferEncodingValueMB = null;
- if (http11)
- transferEncodingValueMB = headers.getValue("transfer-encoding");
- if (transferEncodingValueMB != null) {
- String transferEncodingValue = transferEncodingValueMB.toString();
- // Parse the comma separated list. "identity" codings are ignored
- int startPos = 0;
- int commaPos = transferEncodingValue.indexOf(',');
- String encodingName = null;
- while (commaPos != -1) {
- encodingName = transferEncodingValue.substring
- (startPos, commaPos).toLowerCase(Locale.ENGLISH).trim();
- if (!addInputFilter(inputFilters, encodingName)) {
- // Unsupported transfer encoding
- error = true;
- // 501 - Unimplemented
- response.setStatus(501);
- }
- startPos = commaPos + 1;
- commaPos = transferEncodingValue.indexOf(',', startPos);
- }
- encodingName = transferEncodingValue.substring(startPos)
- .toLowerCase(Locale.ENGLISH).trim();
- if (!addInputFilter(inputFilters, encodingName)) {
- // Unsupported transfer encoding
- error = true;
- // 501 - Unimplemented
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.request.prepare")+
- " Unsupported transfer encoding
\""+encodingName+"\"");
- }
- response.setStatus(501);
- }
- }
-
- // Parse content-length header
- long contentLength = request.getContentLengthLong();
- if (contentLength >= 0 && !contentDelimitation) {
- inputBuffer.addActiveFilter
- (inputFilters[Constants.IDENTITY_FILTER]);
- contentDelimitation = true;
- }
-
- MessageBytes valueMB = headers.getValue("host");
-
- // Check host header
- if (http11 && (valueMB == null)) {
- error = true;
- // 400 - Bad request
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.request.prepare")+
- " host header missing");
- }
- response.setStatus(400);
- }
-
- parseHost(valueMB);
-
- if (!contentDelimitation) {
- // If there's no content length
- // (broken HTTP/1.0 or HTTP/1.1), assume
- // the client is not broken and didn't send a body
- inputBuffer.addActiveFilter
- (inputFilters[Constants.VOID_FILTER]);
- contentDelimitation = true;
- }
-
- }
-
-
- /**
- * Parse host.
- */
- protected void parseHost(MessageBytes valueMB) {
-
- if (valueMB == null || valueMB.isNull()) {
- // HTTP/1.0
- // Default is what the socket tells us. Overriden if a host is
- // found/parsed
- request.setServerPort(socket.getLocalPort());
- InetAddress localAddress = socket.getLocalAddress();
- // Setting the socket-related fields. The adapter doesn't know
- // about socket.
- request.serverName().setString(localAddress.getHostName());
- return;
- }
-
- ByteChunk valueBC = valueMB.getByteChunk();
- byte[] valueB = valueBC.getBytes();
- int valueL = valueBC.getLength();
- int valueS = valueBC.getStart();
- int colonPos = -1;
- if (hostNameC.length < valueL) {
- hostNameC = new char[valueL];
- }
-
- boolean ipv6 = (valueB[valueS] == '[');
- boolean bracketClosed = false;
- for (int i = 0; i < valueL; i++) {
- char b = (char) valueB[i + valueS];
- hostNameC[i] = b;
- if (b == ']') {
- bracketClosed = true;
- } else if (b == ':') {
- if (!ipv6 || bracketClosed) {
- colonPos = i;
- break;
- }
- }
- }
-
- if (colonPos < 0) {
- if (sslSupport == null) {
- // 80 - Default HTTP port
- request.setServerPort(80);
- } else {
- // 443 - Default HTTPS port
- request.setServerPort(443);
- }
- request.serverName().setChars(hostNameC, 0, valueL);
- } else {
-
- request.serverName().setChars(hostNameC, 0, colonPos);
-
- int port = 0;
- int mult = 1;
- for (int i = valueL - 1; i > colonPos; i--) {
- int charValue = HexUtils.DEC[valueB[i + valueS]];
- if (charValue == -1) {
- // Invalid character
- error = true;
- // 400 - Bad request
- response.setStatus(400);
- break;
- }
- port = port + (charValue * mult);
- mult = 10 * mult;
- }
- request.setServerPort(port);
-
- }
-
- }
-
-
- /**
- * Check for compression
- */
- private boolean isCompressable() {
-
- // Nope Compression could works in HTTP 1.0 also
- // cf: mod_deflate
-
- // Compression only since HTTP 1.1
- // if (! http11)
- // return false;
-
- // Check if browser support gzip encoding
- MessageBytes acceptEncodingMB =
- request.getMimeHeaders().getValue("accept-encoding");
-
- if ((acceptEncodingMB == null)
- || (acceptEncodingMB.indexOf("gzip") == -1))
- return false;
-
- // Check if content is not allready gzipped
- MessageBytes contentEncodingMB =
- response.getMimeHeaders().getValue("Content-Encoding");
-
- if ((contentEncodingMB != null)
- && (contentEncodingMB.indexOf("gzip") != -1))
- return false;
-
- // If force mode, allways compress (test purposes only)
- if (compressionLevel == 2)
- return true;
-
- // Check for incompatible Browser
- if (noCompressionUserAgents != null) {
- MessageBytes userAgentValueMB =
- request.getMimeHeaders().getValue("user-agent");
- if(userAgentValueMB != null) {
- String userAgentValue = userAgentValueMB.toString();
-
- // If one Regexp rule match, disable compression
- for (int i = 0; i < noCompressionUserAgents.length; i++)
- if (noCompressionUserAgents[i].matcher(userAgentValue).matches())
- return false;
- }
- }
-
- // Check if suffisant len to trig the compression
- long contentLength = response.getContentLengthLong();
- if ((contentLength == -1)
- || (contentLength > compressionMinSize)) {
- // Check for compatible MIME-TYPE
- if (compressableMimeTypes != null) {
- return (startsWithStringArray(compressableMimeTypes,
- response.getContentType()));
- }
- }
-
- return false;
- }
-
-
- /**
- * When committing the response, we have to validate the set of headers, as
- * well as setup the response filters.
- */
- protected void prepareResponse() {
-
- boolean entityBody = true;
- contentDelimitation = false;
-
- OutputFilter[] outputFilters = outputBuffer.getFilters();
-
- if (http09 == true) {
- // HTTP/0.9
- outputBuffer.addActiveFilter
- (outputFilters[Constants.IDENTITY_FILTER]);
- return;
- }
-
- int statusCode = response.getStatus();
- if ((statusCode == 204) || (statusCode == 205)
- || (statusCode == 304)) {
- // No entity body
- outputBuffer.addActiveFilter
- (outputFilters[Constants.VOID_FILTER]);
- entityBody = false;
- contentDelimitation = true;
- }
-
- MessageBytes methodMB = request.method();
- if (methodMB.equals("HEAD")) {
- // No entity body
- outputBuffer.addActiveFilter
- (outputFilters[Constants.VOID_FILTER]);
- contentDelimitation = true;
- }
-
- // Check for compression
- boolean useCompression = false;
- if (entityBody && (compressionLevel > 0)) {
- useCompression = isCompressable();
-
- // Change content-length to -1 to force chunking
- if (useCompression) {
- response.setContentLength(-1);
- }
- }
-
- MimeHeaders headers = response.getMimeHeaders();
- if (!entityBody) {
- response.setContentLength(-1);
- } else {
- String contentType = response.getContentType();
- if (contentType != null) {
- headers.setValue("Content-Type").setString(contentType);
- }
- String contentLanguage = response.getContentLanguage();
- if (contentLanguage != null) {
- headers.setValue("Content-Language")
- .setString(contentLanguage);
- }
- }
-
- long contentLength = response.getContentLengthLong();
- if (contentLength != -1) {
- headers.setValue("Content-Length").setLong(contentLength);
- outputBuffer.addActiveFilter
- (outputFilters[Constants.IDENTITY_FILTER]);
- contentDelimitation = true;
- } else {
- if (entityBody && http11 && (keepAlive || CHUNK_ON_CLOSE)) {
- outputBuffer.addActiveFilter
- (outputFilters[Constants.CHUNKED_FILTER]);
- contentDelimitation = true;
-
headers.addValue(Constants.TRANSFERENCODING).setString(Constants.CHUNKED);
- } else {
- outputBuffer.addActiveFilter
- (outputFilters[Constants.IDENTITY_FILTER]);
- }
- }
-
- if (useCompression) {
- outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]);
- headers.setValue("Content-Encoding").setString("gzip");
- // Make Proxies happy via Vary (from mod_deflate)
- headers.addValue("Vary").setString("Accept-Encoding");
- }
-
- // Add date header
-
headers.setValue("Date").setString(FastHttpDateFormat.getCurrentDate());
-
- // FIXME: Add transfer encoding header
-
- if ((entityBody) && (!contentDelimitation)) {
- // Mark as close the connection after the request, and add the
- // connection: close header
- keepAlive = false;
- }
-
- // If we know that the request is bad this early, add the
- // Connection: close header.
- keepAlive = keepAlive && !statusDropsConnection(statusCode);
- if (!keepAlive) {
- headers.addValue(Constants.CONNECTION).setString(Constants.CLOSE);
- } else if (!http11 && !error) {
- headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE);
- }
-
- // Build the response header
- outputBuffer.sendStatus();
-
- // Add server header
- if (server != null) {
- headers.setValue("Server").setString(server);
- } else {
- outputBuffer.write(Constants.SERVER_BYTES);
- }
-
- int size = headers.size();
- for (int i = 0; i < size; i++) {
- outputBuffer.sendHeader(headers.getName(i), headers.getValue(i));
- }
- outputBuffer.endHeaders();
-
- }
-
-
- /**
- * Initialize standard input and output filters.
- */
- protected void initializeFilters() {
-
- // Create and add the identity filters.
- inputBuffer.addFilter(new IdentityInputFilter());
- outputBuffer.addFilter(new IdentityOutputFilter());
-
- // Create and add the chunked filters.
- inputBuffer.addFilter(new ChunkedInputFilter());
- outputBuffer.addFilter(new ChunkedOutputFilter());
-
- // Create and add the void filters.
- inputBuffer.addFilter(new VoidInputFilter());
- outputBuffer.addFilter(new VoidOutputFilter());
-
- // Create and add the chunked filters.
- //inputBuffer.addFilter(new GzipInputFilter());
- outputBuffer.addFilter(new GzipOutputFilter());
-
- }
-
-
- /**
- * Add an input filter to the current request.
- *
- * @return false if the encoding was not found (which would mean it is
- * unsupported)
- */
- protected boolean addInputFilter(InputFilter[] inputFilters,
- String encodingName) {
- if (encodingName.equals("identity")) {
- // Skip
- } else if (encodingName.equals("chunked")) {
- inputBuffer.addActiveFilter
- (inputFilters[Constants.CHUNKED_FILTER]);
- contentDelimitation = true;
- } else {
- for (int i = 2; i < inputFilters.length; i++) {
- if (inputFilters[i].getEncodingName()
- .toString().equals(encodingName)) {
- inputBuffer.addActiveFilter(inputFilters[i]);
- return true;
- }
- }
- return false;
- }
- return true;
- }
-
-
- /**
- * Specialized utility method: find a sequence of lower case bytes inside
- * a ByteChunk.
- */
- protected int findBytes(ByteChunk bc, byte[] b) {
-
- byte first = b[0];
- byte[] buff = bc.getBuffer();
- int start = bc.getStart();
- int end = bc.getEnd();
-
- // Look for first char
- int srcEnd = b.length;
-
- for (int i = start; i <= (end - srcEnd); i++) {
- if (Ascii.toLower(buff[i]) != first) continue;
- // found first char, now look for a match
- int myPos = i+1;
- for (int srcPos = 1; srcPos < srcEnd; ) {
- if (Ascii.toLower(buff[myPos++]) != b[srcPos++])
- break;
- if (srcPos == srcEnd) return i - start; // found it
- }
- }
- return -1;
-
- }
-
- /**
- * Determine if we must drop the connection because of the HTTP status
- * code. Use the same list of codes as Apache/httpd.
- */
- protected boolean statusDropsConnection(int status) {
- return status == 400 /* SC_BAD_REQUEST */ ||
- status == 408 /* SC_REQUEST_TIMEOUT */ ||
- status == 411 /* SC_LENGTH_REQUIRED */ ||
- status == 413 /* SC_REQUEST_ENTITY_TOO_LARGE */ ||
- status == 414 /* SC_REQUEST_URI_TOO_LARGE */ ||
- status == 500 /* SC_INTERNAL_SERVER_ERROR */ ||
- status == 503 /* SC_SERVICE_UNAVAILABLE */ ||
- status == 501 /* SC_NOT_IMPLEMENTED */;
- }
-
-}
Deleted: trunk/java/org/apache/coyote/http11/Http11Protocol.java
===================================================================
--- trunk/java/org/apache/coyote/http11/Http11Protocol.java 2012-06-13 08:50:17 UTC (rev
2041)
+++ trunk/java/org/apache/coyote/http11/Http11Protocol.java 2012-06-14 14:11:34 UTC (rev
2042)
@@ -1,812 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.apache.coyote.http11;
-
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.net.ssl.SSLContext;
-
-import org.apache.coyote.Adapter;
-import org.apache.coyote.ProtocolHandler;
-import org.apache.coyote.RequestGroupInfo;
-import org.apache.coyote.RequestInfo;
-import org.apache.tomcat.util.modeler.Registry;
-import org.apache.tomcat.util.net.JIoEndpoint;
-import org.apache.tomcat.util.net.SSLImplementation;
-import org.apache.tomcat.util.net.ServerSocketFactory;
-import org.apache.tomcat.util.net.SocketStatus;
-import org.apache.tomcat.util.net.JIoEndpoint.Handler;
-import org.apache.tomcat.util.res.StringManager;
-
-
-/**
- * Abstract the protocol implementation, including threading, etc.
- * Processor is single threaded and specific to stream-based protocols,
- * will not fit Jk protocols like JNI.
- *
- * @author Remy Maucherat
- * @author Costin Manolache
- */
-public class Http11Protocol
- implements ProtocolHandler, MBeanRegistration {
-
-
- protected static org.jboss.logging.Logger log
- = org.jboss.logging.Logger.getLogger(Http11Protocol.class);
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // ------------------------------------------------------------ Constructor
-
-
- public Http11Protocol() {
- setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
- setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
- //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT);
- setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);
- }
-
-
- // ----------------------------------------------------------------- Fields
-
-
- protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);
- protected JIoEndpoint endpoint = new JIoEndpoint();
-
-
- // *
- protected ObjectName tpOname = null;
- // *
- protected ObjectName rgOname = null;
-
-
- protected ServerSocketFactory socketFactory = null;
- protected SSLImplementation sslImplementation = null;
-
-
- // ----------------------------------------- ProtocolHandler Implementation
- // *
-
-
- protected HashMap<String, Object> attributes = new HashMap<String,
Object>();
-
-
- /**
- * Pass config info
- */
- public void setAttribute(String name, Object value) {
- if (log.isTraceEnabled()) {
- log.trace(sm.getString("http11protocol.setattribute", name,
value));
- }
- attributes.put(name, value);
- }
-
- public Object getAttribute(String key) {
- return attributes.get(key);
- }
-
- public Iterator getAttributeNames() {
- return attributes.keySet().iterator();
- }
-
- /**
- * Set a property.
- */
- public void setProperty(String name, String value) {
- setAttribute(name, value);
- }
-
- /**
- * Get a property
- */
- public String getProperty(String name) {
- return (String)getAttribute(name);
- }
-
- /**
- * The adapter, used to call the connector.
- */
- protected Adapter adapter;
- public void setAdapter(Adapter adapter) { this.adapter = adapter; }
- public Adapter getAdapter() { return adapter; }
-
-
- public boolean hasIoEvents() {
- return false;
- }
-
- public RequestGroupInfo getRequestGroupInfo() {
- return cHandler.global;
- }
-
- public void init() throws Exception {
- endpoint.setName(getName());
- endpoint.setHandler(cHandler);
-
- // Verify the validity of the configured socket factory
- try {
- if (isSSLEnabled()) {
- sslImplementation =
- SSLImplementation.getInstance(sslImplementationName);
- socketFactory = sslImplementation.getServerSocketFactory();
- endpoint.setServerSocketFactory(socketFactory);
- } else if (socketFactoryName != null) {
- socketFactory = (ServerSocketFactory)
Class.forName(socketFactoryName).newInstance();
- endpoint.setServerSocketFactory(socketFactory);
- }
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.socketfactory.initerror"),
- ex);
- throw ex;
- }
-
- if (socketFactory!=null) {
- Iterator<String> attE = attributes.keySet().iterator();
- while( attE.hasNext() ) {
- String key = attE.next();
- Object v=attributes.get(key);
- socketFactory.setAttribute(key, v);
- }
- }
-
- try {
- endpoint.init();
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
- throw ex;
- }
- if (log.isDebugEnabled())
- log.debug(sm.getString("http11protocol.init", getName()));
-
- }
-
- public void start() throws Exception {
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER) {
- if (this.domain != null) {
- try {
- tpOname = new ObjectName
- (domain + ":" + "type=ThreadPool,name=" +
getName());
- Registry.getRegistry(null, null)
- .registerComponent(endpoint, tpOname, null );
- } catch (Exception e) {
- log.error("Can't register endpoint");
- }
- rgOname=new ObjectName
- (domain + ":type=GlobalRequestProcessor,name=" + getName());
- Registry.getRegistry(null, null).registerComponent
- ( cHandler.global, rgOname, null );
- }
- }
- try {
- endpoint.start();
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.endpoint.starterror"), ex);
- throw ex;
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("http11protocol.start", getName()));
- }
-
- public void pause() throws Exception {
- try {
- endpoint.pause();
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.endpoint.pauseerror"), ex);
- throw ex;
- }
- // Wait for a while until all the processors are no longer processing requests
- RequestInfo[] states = cHandler.global.getRequestProcessors();
- int retry = 0;
- boolean done = false;
- while (!done && retry < org.apache.coyote.Constants.MAX_PAUSE_WAIT) {
- retry++;
- done = true;
- for (int i = 0; i < states.length; i++) {
- if (states[i].getStage() == org.apache.coyote.Constants.STAGE_SERVICE) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- ;
- }
- done = false;
- break;
- }
- }
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("http11protocol.pause", getName()));
- }
-
- public void resume() throws Exception {
- try {
- endpoint.resume();
- } catch (Exception ex) {
- log.error(sm.getString("http11protocol.endpoint.resumeerror"),
ex);
- throw ex;
- }
- if (log.isInfoEnabled())
- log.info(sm.getString("http11protocol.resume", getName()));
- }
-
- public void destroy() throws Exception {
- if (log.isInfoEnabled())
- log.info(sm.getString("http11protocol.stop", getName()));
- endpoint.destroy();
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER) {
- if (tpOname!=null)
- Registry.getRegistry(null, null).unregisterComponent(tpOname);
- if (rgOname != null)
- Registry.getRegistry(null, null).unregisterComponent(rgOname);
- }
- }
-
- public String getJmxName() {
- String encodedAddr = "";
- if (getAddress() != null) {
- encodedAddr = "" + getAddress();
- encodedAddr = URLEncoder.encode(encodedAddr.replace('/',
'-').replace(':', '_').replace('%', '-')) +
"-";
- }
- return ("http-" + encodedAddr + endpoint.getPort());
- }
-
- public String getName() {
- String encodedAddr = "";
- if (getAddress() != null) {
- encodedAddr = getAddress() + ":";
- }
- return ("http-" + encodedAddr + endpoint.getPort());
- }
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Processor cache.
- */
- protected int processorCache = -1;
- public int getProcessorCache() { return this.processorCache; }
- public void setProcessorCache(int processorCache) { this.processorCache =
processorCache; }
-
- protected int socketBuffer = 9000;
- public int getSocketBuffer() { return socketBuffer; }
- public void setSocketBuffer(int socketBuffer) { this.socketBuffer = socketBuffer; }
-
- /**
- * This field indicates if the protocol is secure from the perspective of
- * the client (= https is used).
- */
- protected boolean secure;
- public boolean getSecure() { return secure; }
- public void setSecure(boolean b) { secure = b; }
-
- protected boolean SSLEnabled = false;
- public boolean isSSLEnabled() { return SSLEnabled;}
- public void setSSLEnabled(boolean SSLEnabled) {this.SSLEnabled = SSLEnabled;}
-
- /**
- * Name of the socket factory.
- */
- protected String socketFactoryName = null;
- public String getSocketFactory() { return socketFactoryName; }
- public void setSocketFactory(String valueS) { socketFactoryName = valueS; }
-
- /**
- * Name of the SSL implementation.
- */
- protected String sslImplementationName=null;
- public String getSSLImplementation() { return sslImplementationName; }
- public void setSSLImplementation( String valueS) {
- sslImplementationName = valueS;
- setSecure(true);
- }
-
-
- // HTTP
- /**
- * Maximum number of requests which can be performed over a keepalive
- * connection. The default is the same as for Apache HTTP Server.
- */
- protected int maxKeepAliveRequests = (org.apache.tomcat.util.Constants.LOW_MEMORY) ?
1 :
-
Integer.valueOf(System.getProperty("org.apache.coyote.http11.Http11Protocol.MAX_KEEP_ALIVE_REQUESTS",
"-1")).intValue();
- public int getMaxKeepAliveRequests() { return maxKeepAliveRequests; }
- public void setMaxKeepAliveRequests(int mkar) { maxKeepAliveRequests = mkar; }
-
- // HTTP
- /**
- * The number of seconds Tomcat will wait for a subsequent request
- * before closing the connection. The default is the same as for
- * Apache HTTP Server (15 000 milliseconds).
- */
- protected int keepAliveTimeout = -1;
- public int getKeepAliveTimeout() { return keepAliveTimeout; }
- public void setKeepAliveTimeout(int timeout) { keepAliveTimeout = timeout; }
-
- // HTTP
- /**
- * This timeout represents the socket timeout which will be used while
- * the adapter execution is in progress, unless disableUploadTimeout
- * is set to true. The default is the same as for Apache HTTP Server
- * (300 000 milliseconds).
- */
- protected int timeout = 300000;
- public int getTimeout() { return timeout; }
- public void setTimeout(int timeout) { this.timeout = timeout; }
-
-
- // *
- /**
- * Maximum size of the post which will be saved when processing certain
- * requests, such as a POST.
- */
- protected int maxSavePostSize = 4 * 1024;
- public int getMaxSavePostSize() { return maxSavePostSize; }
- public void setMaxSavePostSize(int valueI) { maxSavePostSize = valueI; }
-
-
- // HTTP
- /**
- * Maximum size of the HTTP message header.
- */
- protected int maxHttpHeaderSize =
Integer.valueOf(System.getProperty("org.apache.coyote.http11.Http11Protocol.MAX_HEADER_SIZE",
"8192")).intValue();
- public int getMaxHttpHeaderSize() { return maxHttpHeaderSize; }
- public void setMaxHttpHeaderSize(int valueI) { maxHttpHeaderSize = valueI; }
-
-
- // HTTP
- /**
- * If true, the regular socket timeout will be used for the full duration
- * of the connection.
- */
- protected boolean disableUploadTimeout = true;
- public boolean getDisableUploadTimeout() { return disableUploadTimeout; }
- public void setDisableUploadTimeout(boolean isDisabled) { disableUploadTimeout =
isDisabled; }
-
-
- // HTTP
- /**
- * Integrated compression support.
- */
- protected String compression =
System.getProperty("org.apache.coyote.http11.Http11Protocol.COMPRESSION",
"off");
- public String getCompression() { return compression; }
- public void setCompression(String valueS) { compression = valueS; }
-
-
- // HTTP
- protected String noCompressionUserAgents =
System.getProperty("org.apache.coyote.http11.Http11Protocol.COMPRESSION_RESTRICTED_UA");
- public String getNoCompressionUserAgents() { return noCompressionUserAgents; }
- public void setNoCompressionUserAgents(String valueS) { noCompressionUserAgents =
valueS; }
-
-
- // HTTP
- protected String compressableMimeTypes =
System.getProperty("org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES",
"text/html,text/xml,text/plain");
- public String getCompressableMimeType() { return compressableMimeTypes; }
- public void setCompressableMimeType(String valueS) { compressableMimeTypes = valueS;
}
-
-
- // HTTP
- protected int compressionMinSize =
Integer.valueOf(System.getProperty("org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIN_SIZE",
"2048")).intValue();
- public int getCompressionMinSize() { return compressionMinSize; }
- public void setCompressionMinSize(int valueI) { compressionMinSize = valueI; }
-
-
- // HTTP
- /**
- * User agents regular expressions which should be restricted to HTTP/1.0 support.
- */
- protected String restrictedUserAgents = null;
- public String getRestrictedUserAgents() { return restrictedUserAgents; }
- public void setRestrictedUserAgents(String valueS) { restrictedUserAgents = valueS;
}
-
- // HTTP
- /**
- * Server header.
- */
- protected String server =
System.getProperty("org.apache.coyote.http11.Http11Protocol.SERVER");
- public void setServer( String server ) { this.server = server; }
- public String getServer() { return server; }
-
- public Executor getExecutor() { return endpoint.getExecutor(); }
- public void setExecutor(Executor executor) { endpoint.setExecutor(executor); }
-
- public int getMaxThreads() { return endpoint.getMaxThreads(); }
- public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); }
-
- public int getThreadPriority() { return endpoint.getThreadPriority(); }
- public void setThreadPriority(int threadPriority) {
endpoint.setThreadPriority(threadPriority); }
-
- public int getBacklog() { return endpoint.getBacklog(); }
- public void setBacklog(int backlog) { endpoint.setBacklog(backlog); }
-
- public int getPort() { return endpoint.getPort(); }
- public void setPort(int port) { endpoint.setPort(port); }
-
- public InetAddress getAddress() { return endpoint.getAddress(); }
- public void setAddress(InetAddress ia) { endpoint.setAddress(ia); }
-
- public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); }
- public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay);
}
-
- public int getSoLinger() { return endpoint.getSoLinger(); }
- public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); }
-
- public int getSoTimeout() { return endpoint.getSoTimeout(); }
- public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); }
-
- public void setPollerSize(int pollerSize) { endpoint.setPollerSize(pollerSize); }
- public int getPollerSize() { return endpoint.getPollerSize(); }
-
- // HTTP
- /**
- * Return the Keep-Alive policy for the connection.
- */
- public boolean getKeepAlive() {
- return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1));
- }
-
- // HTTP
- /**
- * Set the keep-alive policy for this connection.
- */
- public void setKeepAlive(boolean keepAlive) {
- if (!keepAlive) {
- setMaxKeepAliveRequests(1);
- }
- }
-
- /*
- * Note: All the following are JSSE/java.io specific attributes.
- */
-
- public String getKeystore() {
- return (String) getAttribute("keystore");
- }
-
- public void setKeystore( String k ) {
- setAttribute("keystore", k);
- }
-
- public String getKeypass() {
- return (String) getAttribute("keypass");
- }
-
- public void setKeypass( String k ) {
- attributes.put("keypass", k);
- //setAttribute("keypass", k);
- }
-
- public String getKeytype() {
- return (String) getAttribute("keystoreType");
- }
-
- public void setKeytype( String k ) {
- setAttribute("keystoreType", k);
- }
-
- public String getClientauth() {
- return (String) getAttribute("clientauth");
- }
-
- public void setClientauth( String k ) {
- setAttribute("clientauth", k);
- }
-
- public String getProtocols() {
- return (String) getAttribute("protocols");
- }
-
- public void setProtocols(String k) {
- setAttribute("protocols", k);
- }
-
- public String getAlgorithm() {
- return (String) getAttribute("algorithm");
- }
-
- public void setAlgorithm( String k ) {
- setAttribute("algorithm", k);
- }
-
- public String getCiphers() {
- return (String) getAttribute("ciphers");
- }
-
- public void setCiphers(String ciphers) {
- setAttribute("ciphers", ciphers);
- }
-
- public String getKeyAlias() {
- return (String) getAttribute("keyAlias");
- }
-
- public void setKeyAlias(String keyAlias) {
- setAttribute("keyAlias", keyAlias);
- }
-
- public SSLContext getSSLContext() {
- return (SSLContext) getAttribute("SSLContext");
- }
-
- public void setSSLContext(SSLContext sslContext) {
- setAttribute("SSLContext", sslContext);
- }
-
- // ----------------------------------- Http11ConnectionHandler Inner Class
-
- protected static class Http11ConnectionHandler implements Handler {
-
- protected Http11Protocol proto;
- protected AtomicLong registerCount = new AtomicLong(0);
- protected RequestGroupInfo global = new RequestGroupInfo();
-
- protected ConcurrentHashMap<Socket, Http11Processor> connections =
- new ConcurrentHashMap<Socket, Http11Processor>();
- protected ConcurrentLinkedQueue<Http11Processor> recycledProcessors =
- new ConcurrentLinkedQueue<Http11Processor>() {
- protected AtomicInteger size = new AtomicInteger(0);
- public boolean offer(Http11Processor processor) {
- boolean offer = (proto.processorCache == -1) ? true : (size.get() <
proto.processorCache);
- //avoid over growing our cache or add after we have stopped
- boolean result = false;
- if ( offer ) {
- result = super.offer(processor);
- if ( result ) {
- size.incrementAndGet();
- }
- }
- if (!result) unregister(processor);
- return result;
- }
-
- public Http11Processor poll() {
- Http11Processor result = super.poll();
- if ( result != null ) {
- size.decrementAndGet();
- }
- return result;
- }
-
- public void clear() {
- Http11Processor next = poll();
- while ( next != null ) {
- unregister(next);
- next = poll();
- }
- super.clear();
- size.set(0);
- }
- };
-
- Http11ConnectionHandler(Http11Protocol proto) {
- this.proto = proto;
- }
-
- public SocketState event(Socket socket, SocketStatus status) {
- Http11Processor result = connections.get(socket);
- SocketState state = SocketState.CLOSED;
- if (result != null) {
- result.startProcessing();
- // Call the appropriate event
- try {
- state = result.event(status);
- } catch (java.net.SocketException e) {
- // SocketExceptions are normal
- Http11Protocol.log.debug
- (sm.getString
- ("http11protocol.proto.socketexception.debug"),
e);
- } catch (java.io.IOException e) {
- // IOExceptions are normal
- Http11Protocol.log.debug
- (sm.getString
- ("http11protocol.proto.ioexception.debug"), e);
- }
- // Future developers: if you discover any other
- // rare-but-nonfatal exceptions, catch them here, and log as
- // above.
- catch (Throwable e) {
- // any other exception or error is odd. Here we log it
- // with "ERROR" level, so it will show up even on
- // less-than-verbose logs.
- Http11Protocol.log.error
- (sm.getString("http11protocol.proto.error"), e);
- } finally {
- if (state != SocketState.LONG) {
- connections.remove(socket);
- recycledProcessors.offer(result);
- } else {
- if (proto.endpoint.isRunning()) {
- proto.endpoint.getEventPoller().add(socket,
result.getTimeout(),
- result.getResumeNotification(), false);
- }
- }
- result.endProcessing();
- }
- }
- return state;
- }
-
- public SocketState process(Socket socket) {
- Http11Processor processor = recycledProcessors.poll();
- try {
-
- if (processor == null) {
- processor = createProcessor();
- }
-
- if (proto.secure && (proto.sslImplementation != null)) {
- processor.setSSLSupport
- (proto.sslImplementation.getSSLSupport(socket));
- } else {
- processor.setSSLSupport(null);
- }
-
- SocketState state = processor.process(socket);
- if (state == SocketState.LONG) {
- // Associate the connection with the processor. The next request
- // processed by this thread will use either a new or a recycled
- // processor.
- connections.put(socket, processor);
- proto.endpoint.getEventPoller().add(socket, processor.getTimeout(),
- processor.getResumeNotification(), false);
- } else {
- recycledProcessors.offer(processor);
- }
- return state;
-
- } catch(java.net.SocketException e) {
- // SocketExceptions are normal
- Http11Protocol.log.debug
- (sm.getString
- ("http11protocol.proto.socketexception.debug"), e);
- } catch (java.io.IOException e) {
- // IOExceptions are normal
- Http11Protocol.log.debug
- (sm.getString
- ("http11protocol.proto.ioexception.debug"), e);
- }
- // Future developers: if you discover any other
- // rare-but-nonfatal exceptions, catch them here, and log as
- // above.
- catch (Throwable e) {
- // any other exception or error is odd. Here we log it
- // with "ERROR" level, so it will show up even on
- // less-than-verbose logs.
- Http11Protocol.log.error
- (sm.getString("http11protocol.proto.error"), e);
- }
- recycledProcessors.offer(processor);
- return SocketState.CLOSED;
- }
-
- protected Http11Processor createProcessor() {
- Http11Processor processor =
- new Http11Processor(proto.maxHttpHeaderSize, proto.endpoint);
- processor.setAdapter(proto.adapter);
- processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
- processor.setKeepAliveTimeout(proto.keepAliveTimeout);
- processor.setTimeout(proto.timeout);
- processor.setDisableUploadTimeout(proto.disableUploadTimeout);
- processor.setCompressionMinSize(proto.compressionMinSize);
- processor.setCompression(proto.compression);
- processor.setNoCompressionUserAgents(proto.noCompressionUserAgents);
- processor.setCompressableMimeTypes(proto.compressableMimeTypes);
- processor.setRestrictedUserAgents(proto.restrictedUserAgents);
- processor.setSocketBuffer(proto.socketBuffer);
- processor.setMaxSavePostSize(proto.maxSavePostSize);
- processor.setServer(proto.server);
- register(processor);
- return processor;
- }
-
- protected void register(Http11Processor processor) {
- RequestInfo rp = processor.getRequest().getRequestProcessor();
- rp.setGlobalProcessor(global);
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER &&
proto.getDomain() != null) {
- synchronized (this) {
- try {
- long count = registerCount.incrementAndGet();
- ObjectName rpName = new ObjectName
- (proto.getDomain() +
":type=RequestProcessor,worker="
- + proto.getJmxName() + ",name=HttpRequest" +
count);
- if (log.isDebugEnabled()) {
- log.debug("Register " + rpName);
- }
- Registry.getRegistry(null, null).registerComponent(rp, rpName,
null);
- rp.setRpName(rpName);
- } catch (Exception e) {
- log.warn("Error registering request");
- }
- }
- }
- }
-
- protected void unregister(Http11Processor processor) {
- RequestInfo rp = processor.getRequest().getRequestProcessor();
- rp.setGlobalProcessor(null);
- if (org.apache.tomcat.util.Constants.ENABLE_MODELER &&
proto.getDomain() != null) {
- synchronized (this) {
- try {
- ObjectName rpName = rp.getRpName();
- if (log.isDebugEnabled()) {
- log.debug("Unregister " + rpName);
- }
- Registry.getRegistry(null, null).unregisterComponent(rpName);
- rp.setRpName(null);
- } catch (Exception e) {
- log.warn("Error unregistering request", e);
- }
- }
- }
- }
-
- }
-
-
- // -------------------- JMX related methods --------------------
-
- // *
- protected String domain;
- protected ObjectName oname;
- protected MBeanServer mserver;
-
- public ObjectName getObjectName() {
- return oname;
- }
-
- public String getDomain() {
- return domain;
- }
-
- public ObjectName preRegister(MBeanServer server,
- ObjectName name) throws Exception {
- oname=name;
- mserver=server;
- domain=name.getDomain();
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
-
- public void postDeregister() {
- }
-}
Deleted: trunk/java/org/apache/coyote/http11/InternalInputBuffer.java
===================================================================
--- trunk/java/org/apache/coyote/http11/InternalInputBuffer.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/coyote/http11/InternalInputBuffer.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -1,793 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.coyote.http11;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.EOFException;
-
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.res.StringManager;
-
-import org.apache.coyote.InputBuffer;
-import org.apache.coyote.Request;
-
-/**
- * Implementation of InputBuffer which provides HTTP request header parsing as
- * well as transfer decoding.
- *
- * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
- */
-public class InternalInputBuffer implements InputBuffer {
-
-
- // -------------------------------------------------------------- Constants
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Default constructor.
- */
- public InternalInputBuffer(Request request) {
- this(request, Constants.DEFAULT_HTTP_HEADER_BUFFER_SIZE);
- }
-
-
- /**
- * Alternate constructor.
- */
- public InternalInputBuffer(Request request, int headerBufferSize) {
-
- this.request = request;
- headers = request.getMimeHeaders();
-
- buf = new byte[headerBufferSize];
-
- inputStreamInputBuffer = new InputStreamInputBuffer();
-
- filterLibrary = new InputFilter[0];
- activeFilters = new InputFilter[0];
- lastActiveFilter = -1;
-
- parsingHeader = true;
- swallowInput = true;
-
- }
-
-
- // -------------------------------------------------------------- Variables
-
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * Associated Coyote request.
- */
- protected Request request;
-
-
- /**
- * Headers of the associated request.
- */
- protected MimeHeaders headers;
-
-
- /**
- * State.
- */
- protected boolean parsingHeader;
-
-
- /**
- * Swallow input ? (in the case of an expectation)
- */
- protected boolean swallowInput;
-
-
- /**
- * Pointer to the current read buffer.
- */
- protected byte[] buf;
-
-
- /**
- * Last valid byte.
- */
- protected int lastValid;
-
-
- /**
- * Position in the buffer.
- */
- protected int pos;
-
-
- /**
- * Pos of the end of the header in the buffer, which is also the
- * start of the body.
- */
- protected int end;
-
-
- /**
- * Underlying input stream.
- */
- protected InputStream inputStream;
-
-
- /**
- * Underlying input buffer.
- */
- protected InputBuffer inputStreamInputBuffer;
-
-
- /**
- * Filter library.
- * Note: Filter[0] is always the "chunked" filter.
- */
- protected InputFilter[] filterLibrary;
-
-
- /**
- * Active filters (in order).
- */
- protected InputFilter[] activeFilters;
-
-
- /**
- * Index of the last active filter.
- */
- protected int lastActiveFilter;
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Set the underlying socket input stream.
- */
- public void setInputStream(InputStream inputStream) {
-
- // FIXME: Check for null ?
-
- this.inputStream = inputStream;
-
- }
-
-
- /**
- * Get the underlying socket input stream.
- */
- public InputStream getInputStream() {
-
- return inputStream;
-
- }
-
-
- /**
- * Add an input filter to the filter library.
- */
- public void addFilter(InputFilter filter) {
-
- // FIXME: Check for null ?
-
- InputFilter[] newFilterLibrary =
- new InputFilter[filterLibrary.length + 1];
- for (int i = 0; i < filterLibrary.length; i++) {
- newFilterLibrary[i] = filterLibrary[i];
- }
- newFilterLibrary[filterLibrary.length] = filter;
- filterLibrary = newFilterLibrary;
-
- activeFilters = new InputFilter[filterLibrary.length];
-
- }
-
-
- /**
- * Get filters.
- */
- public InputFilter[] getFilters() {
-
- return filterLibrary;
-
- }
-
-
- /**
- * Clear filters.
- */
- public void clearFilters() {
-
- filterLibrary = new InputFilter[0];
- lastActiveFilter = -1;
-
- }
-
-
- /**
- * Add an input filter to the filter library.
- */
- public void addActiveFilter(InputFilter filter) {
-
- if (lastActiveFilter == -1) {
- filter.setBuffer(inputStreamInputBuffer);
- } else {
- for (int i = 0; i <= lastActiveFilter; i++) {
- if (activeFilters[i] == filter)
- return;
- }
- filter.setBuffer(activeFilters[lastActiveFilter]);
- }
-
- activeFilters[++lastActiveFilter] = filter;
-
- filter.setRequest(request);
-
- }
-
-
- /**
- * Set the swallow input flag.
- */
- public void setSwallowInput(boolean swallowInput) {
- this.swallowInput = swallowInput;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Recycle the input buffer. This should be called when closing the
- * connection.
- */
- public void recycle() {
-
- // Recycle Request object
- request.recycle();
-
- inputStream = null;
- lastValid = 0;
- pos = 0;
- lastActiveFilter = -1;
- parsingHeader = true;
- swallowInput = true;
-
- }
-
-
- /**
- * End processing of current HTTP request.
- * Note: All bytes of the current request should have been already
- * consumed. This method only resets all the pointers so that we are ready
- * to parse the next HTTP request.
- */
- public boolean nextRequest() {
-
- // Recycle Request object
- request.recycle();
-
- // Copy leftover bytes to the beginning of the buffer
- if (lastValid - pos > 0) {
- int npos = 0;
- int opos = pos;
- while (lastValid - opos > opos - npos) {
- System.arraycopy(buf, opos, buf, npos, opos - npos);
- npos += pos;
- opos += pos;
- }
- System.arraycopy(buf, opos, buf, npos, lastValid - opos);
- }
-
- // Recycle filters
- for (int i = 0; i <= lastActiveFilter; i++) {
- activeFilters[i].recycle();
- }
-
- // Reset pointers
- lastValid = lastValid - pos;
- pos = 0;
- lastActiveFilter = -1;
- parsingHeader = true;
- swallowInput = true;
-
- return (lastValid > 0);
-
- }
-
-
- /**
- * End request (consumes leftover bytes).
- *
- * @throws IOException an undelying I/O error occured
- */
- public void endRequest()
- throws IOException {
-
- if (swallowInput && (lastActiveFilter != -1)) {
- int extraBytes = (int) activeFilters[lastActiveFilter].end();
- pos = pos - extraBytes;
- }
-
- }
-
-
- /**
- * Read the request line. This function is meant to be used during the
- * HTTP request header parsing. Do NOT attempt to read the request body
- * using it.
- *
- * @throws IOException If an exception occurs during the underlying socket
- * read operations, or if the given buffer is not big enough to accomodate
- * the whole line.
- */
- public void parseRequestLine()
- throws IOException {
-
- int start = 0;
-
- //
- // Skipping blank lines
- //
-
- byte chr = 0;
- do {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- chr = buf[pos++];
-
- } while ((chr == Constants.CR) || (chr == Constants.LF));
-
- pos--;
-
- // Mark the current buffer position
- start = pos;
-
- //
- // Reading the method name
- // Method name is always US-ASCII
- //
-
- boolean space = false;
-
- while (!space) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- // Spec says single SP but it also says be tolerant of HT
- if (buf[pos] == Constants.SP || buf[pos] == Constants.HT) {
- space = true;
- request.method().setBytes(buf, start, pos - start);
- }
-
- pos++;
-
- }
-
- // Spec says single SP but also says be tolerant of multiple and/or HT
- while (space) {
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
- if (buf[pos] == Constants.SP || buf[pos] == Constants.HT) {
- pos++;
- } else {
- space = false;
- }
- }
-
- // Mark the current buffer position
- start = pos;
- int end = 0;
- int questionPos = -1;
-
- //
- // Reading the URI
- //
-
- boolean eol = false;
-
- while (!space) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- // Spec says single SP but it also says be tolerant of HT
- if (buf[pos] == Constants.SP || buf[pos] == Constants.HT) {
- space = true;
- end = pos;
- } else if ((buf[pos] == Constants.CR)
- || (buf[pos] == Constants.LF)) {
- // HTTP/0.9 style request
- eol = true;
- space = true;
- end = pos;
- } else if ((buf[pos] == Constants.QUESTION)
- && (questionPos == -1)) {
- questionPos = pos;
- }
-
- pos++;
-
- }
-
- request.unparsedURI().setBytes(buf, start, end - start);
- if (questionPos >= 0) {
- request.queryString().setBytes(buf, questionPos + 1,
- end - questionPos - 1);
- request.requestURI().setBytes(buf, start, questionPos - start);
- } else {
- request.requestURI().setBytes(buf, start, end - start);
- }
-
- // Spec says single SP but also says be tolerant of multiple and/or HT
- while (space) {
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
- if (buf[pos] == Constants.SP || buf[pos] == Constants.HT) {
- pos++;
- } else {
- space = false;
- }
- }
-
- // Mark the current buffer position
- start = pos;
- end = 0;
-
- //
- // Reading the protocol
- // Protocol is always US-ASCII
- //
-
- while (!eol) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- if (buf[pos] == Constants.CR) {
- end = pos;
- } else if (buf[pos] == Constants.LF) {
- if (end == 0)
- end = pos;
- eol = true;
- }
-
- pos++;
-
- }
-
- if ((end - start) > 0) {
- request.protocol().setBytes(buf, start, end - start);
- } else {
- request.protocol().setString("");
- }
-
- }
-
-
- /**
- * Parse the HTTP headers.
- */
- public void parseHeaders()
- throws IOException {
-
- while (parseHeader()) {
- }
-
- parsingHeader = false;
- end = pos;
-
- }
-
-
- /**
- * Parse an HTTP header.
- *
- * @return false after reading a blank line (which indicates that the
- * HTTP header parsing is done
- */
- public boolean parseHeader()
- throws IOException {
-
- //
- // Check for blank line
- //
-
- byte chr = 0;
- while (true) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- chr = buf[pos];
-
- if ((chr == Constants.CR) || (chr == Constants.LF)) {
- if (chr == Constants.LF) {
- pos++;
- return false;
- }
- } else {
- break;
- }
-
- pos++;
-
- }
-
- // Mark the current buffer position
- int start = pos;
-
- //
- // Reading the header name
- // Header name is always US-ASCII
- //
-
- boolean colon = false;
- MessageBytes headerValue = null;
-
- while (!colon) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- if (buf[pos] == Constants.COLON) {
- colon = true;
- headerValue = headers.addValue(buf, start, pos - start);
- }
- chr = buf[pos];
- if ((chr >= Constants.A) && (chr <= Constants.Z)) {
- buf[pos] = (byte) (chr - Constants.LC_OFFSET);
- }
-
- pos++;
-
- }
-
- // Mark the current buffer position
- start = pos;
- int realPos = pos;
-
- //
- // Reading the header value (which can be spanned over multiple lines)
- //
-
- boolean eol = false;
- boolean validLine = true;
-
- while (validLine) {
-
- boolean space = true;
-
- // Skipping spaces
- while (space) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- if ((buf[pos] == Constants.SP) || (buf[pos] == Constants.HT)) {
- pos++;
- } else {
- space = false;
- }
-
- }
-
- int lastSignificantChar = realPos;
-
- // Reading bytes until the end of the line
- while (!eol) {
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- if (buf[pos] == Constants.CR) {
- } else if (buf[pos] == Constants.LF) {
- eol = true;
- } else if (buf[pos] == Constants.SP) {
- buf[realPos] = buf[pos];
- realPos++;
- } else {
- buf[realPos] = buf[pos];
- realPos++;
- lastSignificantChar = realPos;
- }
-
- pos++;
-
- }
-
- realPos = lastSignificantChar;
-
- // Checking the first character of the new line. If the character
- // is a LWS, then it's a multiline header
-
- // Read new bytes if needed
- if (pos >= lastValid) {
- if (!fill())
- throw new EOFException(sm.getString("iib.eof.error"));
- }
-
- chr = buf[pos];
- if ((chr != Constants.SP) && (chr != Constants.HT)) {
- validLine = false;
- } else {
- eol = false;
- // Copying one extra space in the buffer (since there must
- // be at least one space inserted between the lines)
- buf[realPos] = chr;
- realPos++;
- }
-
- }
-
- // Set the header value
- headerValue.setBytes(buf, start, realPos - start);
-
- return true;
-
- }
-
-
- // ---------------------------------------------------- InputBuffer Methods
-
-
- /**
- * Read some bytes.
- */
- public int doRead(ByteChunk chunk, Request req)
- throws IOException {
-
- if (lastActiveFilter == -1)
- return inputStreamInputBuffer.doRead(chunk, req);
- else
- return activeFilters[lastActiveFilter].doRead(chunk,req);
-
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Fill the internal buffer using data from the undelying input stream.
- *
- * @return false if at end of stream
- */
- protected boolean fill()
- throws IOException {
-
- int nRead = 0;
-
- if (parsingHeader) {
-
- if (lastValid == buf.length) {
- throw new IllegalArgumentException
- (sm.getString("iib.requestheadertoolarge.error"));
- }
-
- nRead = inputStream.read(buf, pos, buf.length - lastValid);
- if (nRead > 0) {
- lastValid = pos + nRead;
- }
-
- } else {
-
- if (buf.length - end < 4500) {
- // In this case, the request header was really large, so we allocate a
- // brand new one; the old one will get GCed when subsequent requests
- // clear all references
- buf = new byte[buf.length];
- end = 0;
- }
- pos = end;
- lastValid = pos;
- nRead = inputStream.read(buf, pos, buf.length - lastValid);
- if (nRead > 0) {
- lastValid = pos + nRead;
- }
-
- }
-
- return (nRead > 0);
-
- }
-
-
- // ------------------------------------- InputStreamInputBuffer Inner Class
-
-
- /**
- * This class is an input buffer which will read its data from an input
- * stream.
- */
- protected class InputStreamInputBuffer
- implements InputBuffer {
-
-
- /**
- * Read bytes into the specified chunk.
- */
- public int doRead(ByteChunk chunk, Request req )
- throws IOException {
-
- if (pos >= lastValid) {
- if (!fill())
- return -1;
- }
-
- int length = lastValid - pos;
- chunk.setBytes(buf, pos, length);
- pos = lastValid;
-
- return (length);
-
- }
-
-
- }
-
-
-}
Deleted: trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java
===================================================================
--- trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -1,762 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.coyote.http11;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.HttpMessages;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.res.StringManager;
-
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.OutputBuffer;
-import org.apache.coyote.Response;
-
-/**
- * Output buffer.
- *
- * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
- */
-public class InternalOutputBuffer
- implements OutputBuffer, ByteChunk.ByteOutputChannel {
-
- // -------------------------------------------------------------- Constants
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Default constructor.
- */
- public InternalOutputBuffer(Response response) {
- this(response, Constants.DEFAULT_HTTP_HEADER_BUFFER_SIZE);
- }
-
-
- /**
- * Alternate constructor.
- */
- public InternalOutputBuffer(Response response, int headerBufferSize) {
-
- this.response = response;
-
- headers = response.getMimeHeaders();
-
- buf = new byte[headerBufferSize];
-
- outputStreamOutputBuffer = new OutputStreamOutputBuffer();
-
- filterLibrary = new OutputFilter[0];
- activeFilters = new OutputFilter[0];
- lastActiveFilter = -1;
-
- socketBuffer = new ByteChunk();
- socketBuffer.setByteOutputChannel(this);
-
- committed = false;
- finished = false;
-
- }
-
-
- // -------------------------------------------------------------- Variables
-
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * Associated Coyote response.
- */
- protected Response response;
-
-
- /**
- * Headers of the associated request.
- */
- protected MimeHeaders headers;
-
-
- /**
- * Committed flag.
- */
- protected boolean committed;
-
-
- /**
- * Finished flag.
- */
- protected boolean finished;
-
-
- /**
- * The buffer used for header composition.
- */
- protected byte[] buf;
-
-
- /**
- * Position in the buffer.
- */
- protected int pos;
-
-
- /**
- * Underlying output stream.
- */
- protected OutputStream outputStream;
-
-
- /**
- * Underlying output buffer.
- */
- protected OutputBuffer outputStreamOutputBuffer;
-
-
- /**
- * Filter library.
- * Note: Filter[0] is always the "chunked" filter.
- */
- protected OutputFilter[] filterLibrary;
-
-
- /**
- * Active filter (which is actually the top of the pipeline).
- */
- protected OutputFilter[] activeFilters;
-
-
- /**
- * Index of the last active filter.
- */
- protected int lastActiveFilter;
-
-
- /**
- * Socket buffer.
- */
- protected ByteChunk socketBuffer;
-
-
- /**
- * Socket buffer (extra buffering to reduce number of packets sent).
- */
- protected boolean useSocketBuffer = false;
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Set the underlying socket output stream.
- */
- public void setOutputStream(OutputStream outputStream) {
-
- // FIXME: Check for null ?
-
- this.outputStream = outputStream;
-
- }
-
-
- /**
- * Get the underlying socket output stream.
- */
- public OutputStream getOutputStream() {
-
- return outputStream;
-
- }
-
-
- /**
- * Set the socket buffer size.
- */
- public void setSocketBuffer(int socketBufferSize) {
-
- if (socketBufferSize > 500) {
- useSocketBuffer = true;
- socketBuffer.allocate(socketBufferSize, socketBufferSize);
- } else {
- useSocketBuffer = false;
- }
-
- }
-
-
- /**
- * Add an output filter to the filter library.
- */
- public void addFilter(OutputFilter filter) {
-
- OutputFilter[] newFilterLibrary =
- new OutputFilter[filterLibrary.length + 1];
- for (int i = 0; i < filterLibrary.length; i++) {
- newFilterLibrary[i] = filterLibrary[i];
- }
- newFilterLibrary[filterLibrary.length] = filter;
- filterLibrary = newFilterLibrary;
-
- activeFilters = new OutputFilter[filterLibrary.length];
-
- }
-
-
- /**
- * Get filters.
- */
- public OutputFilter[] getFilters() {
-
- return filterLibrary;
-
- }
-
-
- /**
- * Clear filters.
- */
- public void clearFilters() {
-
- filterLibrary = new OutputFilter[0];
- lastActiveFilter = -1;
-
- }
-
-
- /**
- * Add an output filter to the filter library.
- */
- public void addActiveFilter(OutputFilter filter) {
-
- if (lastActiveFilter == -1) {
- filter.setBuffer(outputStreamOutputBuffer);
- } else {
- for (int i = 0; i <= lastActiveFilter; i++) {
- if (activeFilters[i] == filter)
- return;
- }
- filter.setBuffer(activeFilters[lastActiveFilter]);
- }
-
- activeFilters[++lastActiveFilter] = filter;
-
- filter.setResponse(response);
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Flush the response.
- *
- * @throws IOException an undelying I/O error occured
- */
- public void flush()
- throws IOException {
-
- if (!committed) {
-
- // Send the connector a request for commit. The connector should
- // then validate the headers, send them (using sendHeader) and
- // set the filters accordingly.
- response.action(ActionCode.ACTION_COMMIT, null);
-
- }
-
- // Flush the current buffer
- if (useSocketBuffer) {
- socketBuffer.flushBuffer();
- }
-
- }
-
-
- /**
- * Recycle the output buffer. This should be called when closing the
- * connection.
- */
- public void recycle() {
-
- // Recycle Request object
- response.recycle();
- socketBuffer.recycle();
-
- outputStream = null;
- pos = 0;
- lastActiveFilter = -1;
- committed = false;
- finished = false;
-
- }
-
-
- /**
- * End processing of current HTTP request.
- * Note: All bytes of the current request should have been already
- * consumed. This method only resets all the pointers so that we are ready
- * to parse the next HTTP request.
- */
- public void nextRequest() {
-
- // Recycle Request object
- response.recycle();
- socketBuffer.recycle();
-
- // Recycle filters
- for (int i = 0; i <= lastActiveFilter; i++) {
- activeFilters[i].recycle();
- }
-
- // Reset pointers
- pos = 0;
- lastActiveFilter = -1;
- committed = false;
- finished = false;
-
- }
-
-
- /**
- * End request.
- *
- * @throws IOException an undelying I/O error occured
- */
- public void endRequest()
- throws IOException {
-
- if (!committed) {
-
- // Send the connector a request for commit. The connector should
- // then validate the headers, send them (using sendHeader) and
- // set the filters accordingly.
- response.action(ActionCode.ACTION_COMMIT, null);
-
- }
-
- if (finished)
- return;
-
- if (lastActiveFilter != -1)
- activeFilters[lastActiveFilter].end();
-
- if (useSocketBuffer) {
- socketBuffer.flushBuffer();
- }
-
- finished = true;
-
- }
-
-
- // ------------------------------------------------ HTTP/1.1 Output Methods
-
-
- /**
- * Send an acknoledgement.
- */
- public void sendAck()
- throws IOException {
-
- if (!committed)
- outputStream.write(Constants.ACK_BYTES);
-
- }
-
-
- /**
- * Send the response status line.
- */
- public void sendStatus() {
-
- // Write protocol name
- write(Constants.HTTP_11_BYTES);
- buf[pos++] = Constants.SP;
-
- // Write status code
- int status = response.getStatus();
- switch (status) {
- case 200:
- write(Constants._200_BYTES);
- break;
- case 400:
- write(Constants._400_BYTES);
- break;
- case 404:
- write(Constants._404_BYTES);
- break;
- default:
- write(status);
- }
-
- buf[pos++] = Constants.SP;
-
- // Write message
- String message = null;
- if (org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER) {
- message = response.getMessage();
- }
- if (message == null) {
- write(getMessage(status));
- } else {
- write(message.replace('\n', ' ').replace('\r', '
'));
- }
-
- // End the response status line
- if (org.apache.coyote.Constants.IS_SECURITY_ENABLED){
- AccessController.doPrivileged(
- new PrivilegedAction(){
- public Object run(){
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
- return null;
- }
- }
- );
- } else {
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
- }
-
- }
-
- private String getMessage(final int message){
- if (org.apache.coyote.Constants.IS_SECURITY_ENABLED){
- return (String)AccessController.doPrivileged(
- new PrivilegedAction(){
- public Object run(){
- return HttpMessages.getMessage(message);
- }
- }
- );
- } else {
- return HttpMessages.getMessage(message);
- }
- }
-
- /**
- * Send a header.
- *
- * @param name Header name
- * @param value Header value
- */
- public void sendHeader(MessageBytes name, MessageBytes value) {
-
- if (name.getLength() > 0 && !value.isNull()) {
- write(name);
- buf[pos++] = Constants.COLON;
- buf[pos++] = Constants.SP;
- write(value);
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
- }
-
- }
-
-
- /**
- * Send a header.
- *
- * @param name Header name
- * @param value Header value
- */
- public void sendHeader(ByteChunk name, ByteChunk value) {
-
- write(name);
- buf[pos++] = Constants.COLON;
- buf[pos++] = Constants.SP;
- write(value);
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
-
- }
-
-
- /**
- * Send a header.
- *
- * @param name Header name
- * @param value Header value
- */
- public void sendHeader(String name, String value) {
-
- write(name);
- buf[pos++] = Constants.COLON;
- buf[pos++] = Constants.SP;
- write(value);
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
-
- }
-
-
- /**
- * End the header block.
- */
- public void endHeaders() {
-
- buf[pos++] = Constants.CR;
- buf[pos++] = Constants.LF;
-
- }
-
-
- // --------------------------------------------------- OutputBuffer Methods
-
-
- /**
- * Write the contents of a byte chunk.
- *
- * @param chunk byte chunk
- * @return number of bytes written
- * @throws IOException an undelying I/O error occured
- */
- public int doWrite(ByteChunk chunk, Response res)
- throws IOException {
-
- if (!committed) {
-
- // Send the connector a request for commit. The connector should
- // then validate the headers, send them (using sendHeaders) and
- // set the filters accordingly.
- response.action(ActionCode.ACTION_COMMIT, null);
-
- }
-
- if (lastActiveFilter == -1)
- return outputStreamOutputBuffer.doWrite(chunk, res);
- else
- return activeFilters[lastActiveFilter].doWrite(chunk, res);
-
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Commit the response.
- *
- * @throws IOException an undelying I/O error occured
- */
- protected void commit()
- throws IOException {
-
- // The response is now committed
- committed = true;
- response.setCommitted(true);
-
- if (pos > 0) {
- // Sending the response header buffer
- if (useSocketBuffer) {
- socketBuffer.append(buf, 0, pos);
- } else {
- outputStream.write(buf, 0, pos);
- }
- }
-
- }
-
-
- /**
- * This method will write the contents of the specyfied message bytes
- * buffer to the output stream, without filtering. This method is meant to
- * be used to write the response header.
- *
- * @param mb data to be written
- */
- protected void write(MessageBytes mb) {
-
- if (mb.getType() == MessageBytes.T_BYTES) {
- ByteChunk bc = mb.getByteChunk();
- write(bc);
- } else if (mb.getType() == MessageBytes.T_CHARS) {
- CharChunk cc = mb.getCharChunk();
- write(cc);
- } else {
- write(mb.toString());
- }
-
- }
-
-
- /**
- * This method will write the contents of the specyfied message bytes
- * buffer to the output stream, without filtering. This method is meant to
- * be used to write the response header.
- *
- * @param bc data to be written
- */
- protected void write(ByteChunk bc) {
-
- // Writing the byte chunk to the output buffer
- int length = bc.getLength();
- System.arraycopy(bc.getBytes(), bc.getStart(), buf, pos, length);
- pos = pos + length;
-
- }
-
-
- /**
- * This method will write the contents of the specyfied char
- * buffer to the output stream, without filtering. This method is meant to
- * be used to write the response header.
- *
- * @param cc data to be written
- */
- protected void write(CharChunk cc) {
-
- int start = cc.getStart();
- int end = cc.getEnd();
- char[] cbuf = cc.getBuffer();
- for (int i = start; i < end; i++) {
- char c = cbuf[i];
- // Note: This is clearly incorrect for many strings,
- // but is the only consistent approach within the current
- // servlet framework. It must suffice until servlet output
- // streams properly encode their output.
- if (((c <= 31) && (c != 9)) || c == 127 || c > 255) {
- c = ' ';
- }
- buf[pos++] = (byte) c;
- }
-
- }
-
-
- /**
- * This method will write the contents of the specyfied byte
- * buffer to the output stream, without filtering. This method is meant to
- * be used to write the response header.
- *
- * @param b data to be written
- */
- public void write(byte[] b) {
-
- // Writing the byte chunk to the output buffer
- System.arraycopy(b, 0, buf, pos, b.length);
- pos = pos + b.length;
-
- }
-
-
- /**
- * This method will write the contents of the specyfied String to the
- * output stream, without filtering. This method is meant to be used to
- * write the response header.
- *
- * @param s data to be written
- */
- protected void write(String s) {
-
- if (s == null)
- return;
-
- // From the Tomcat 3.3 HTTP/1.0 connector
- int len = s.length();
- for (int i = 0; i < len; i++) {
- char c = s.charAt (i);
- // Note: This is clearly incorrect for many strings,
- // but is the only consistent approach within the current
- // servlet framework. It must suffice until servlet output
- // streams properly encode their output.
- if ((c <= 31) && (c != 9)) {
- c = ' ';
- } else if (c == 127) {
- c = ' ';
- }
- buf[pos++] = (byte) c;
- }
-
- }
-
-
- /**
- * This method will print the specified integer to the output stream,
- * without filtering. This method is meant to be used to write the
- * response header.
- *
- * @param i data to be written
- */
- protected void write(int i) {
-
- write(String.valueOf(i));
-
- }
-
-
- /**
- * Callback to write data from the buffer.
- */
- public void realWriteBytes(byte cbuf[], int off, int len)
- throws IOException {
- if (len > 0) {
- outputStream.write(cbuf, off, len);
- }
- }
-
-
- // ----------------------------------- OutputStreamOutputBuffer Inner Class
-
-
- /**
- * This class is an output buffer which will write data to an output
- * stream.
- */
- protected class OutputStreamOutputBuffer
- implements OutputBuffer {
-
-
- /**
- * Write chunk.
- */
- public int doWrite(ByteChunk chunk, Response res)
- throws IOException {
-
- int length = chunk.getLength();
- if (useSocketBuffer) {
- socketBuffer.append(chunk.getBuffer(), chunk.getStart(),
- length);
- } else {
- outputStream.write(chunk.getBuffer(), chunk.getStart(),
- length);
- }
- return length;
-
- }
-
-
- }
-
-
-}
Deleted: trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java 2012-06-13
08:50:17 UTC (rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java 2012-06-14
14:11:34 UTC (rev 2042)
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package
org.apache.tomcat.util.net;
-
-import java.io.*;
-import java.net.*;
-
-/**
- * Default server socket factory. Doesn't do much except give us
- * plain ol' server sockets.
- *
- * @author db(a)eng.sun.com
- * @author Harish Prabandham
- */
-
-// Default implementation of server sockets.
-
-//
-// WARNING: Some of the APIs in this class are used by J2EE.
-// Please talk to harishp(a)eng.sun.com before making any changes.
-//
-class DefaultServerSocketFactory extends ServerSocketFactory {
-
- DefaultServerSocketFactory () {
- /* NOTHING */
- }
-
- public ServerSocket createSocket (int port)
- throws IOException {
- return new ServerSocket (port);
- }
-
- public ServerSocket createSocket (int port, int backlog)
- throws IOException {
- return new ServerSocket (port, backlog);
- }
-
- public ServerSocket createSocket (int port, int backlog,
- InetAddress ifAddress)
- throws IOException {
- return new ServerSocket (port, backlog, ifAddress);
- }
-
- public Socket acceptSocket(ServerSocket socket)
- throws IOException {
- return socket.accept();
- }
-
- public void handshake(Socket sock)
- throws IOException {
- ; // NOOP
- }
-
-
- }
Deleted: trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java 2012-06-13 08:50:17 UTC (rev
2041)
+++ trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java 2012-06-14 14:11:34 UTC (rev
2042)
@@ -1,1328 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package
org.apache.tomcat.util.net;
-
-import java.io.IOException;
-import java.net.BindException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.Executor;
-
-import org.apache.tomcat.util.res.StringManager;
-import org.jboss.logging.Logger;
-
-/**
- * Handle incoming TCP connections.
- *
- * This class implement a simple server model: one listener thread accepts on a socket
and
- * creates a new worker thread for each incoming connection.
- *
- * More advanced Endpoints will reuse the threads, use queues, etc.
- *
- * @author James Duncan Davidson
- * @author Jason Hunter
- * @author James Todd
- * @author Costin Manolache
- * @author Gal Shachor
- * @author Yoav Shapira
- * @author Remy Maucherat
- */
-public class JIoEndpoint {
-
-
- // -------------------------------------------------------------- Constants
-
-
- protected static Logger log = Logger.getLogger(JIoEndpoint.class);
-
- protected StringManager sm =
- StringManager.getManager("org.apache.tomcat.util.net.res");
-
-
- // ----------------------------------------------------------------- Fields
-
-
- /**
- * Available workers.
- */
- protected WorkerStack workers = null;
-
-
- /**
- * Running state of the endpoint.
- */
- protected volatile boolean running = false;
-
-
- /**
- * Will be set to true whenever the endpoint is paused.
- */
- protected volatile boolean paused = false;
-
-
- /**
- * Track the initialization state of the endpoint.
- */
- protected boolean initialized = false;
-
-
- /**
- * Current worker threads busy count.
- */
- protected int curThreadsBusy = 0;
-
-
- /**
- * Current worker threads count.
- */
- protected int curThreads = 0;
-
-
- /**
- * Sequence number used to generate thread names.
- */
- protected int sequence = 0;
-
-
- /**
- * Associated server socket.
- */
- protected ServerSocket serverSocket = null;
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Acceptor thread count.
- */
- protected int acceptorThreadCount = 0;
- public void setAcceptorThreadCount(int acceptorThreadCount) {
this.acceptorThreadCount = acceptorThreadCount; }
- public int getAcceptorThreadCount() { return acceptorThreadCount; }
-
-
- /**
- * External Executor based thread pool.
- */
- protected Executor executor = null;
- public void setExecutor(Executor executor) { this.executor = executor; }
- public Executor getExecutor() { return executor; }
-
-
- /**
- * Maximum amount of worker threads.
- */
- protected int maxThreads = (org.apache.tomcat.util.Constants.LOW_MEMORY) ? 64 :
((Constants.MAX_THREADS == -1) ? 512 * Runtime.getRuntime().availableProcessors() :
Constants.MAX_THREADS);
- public void setMaxThreads(int maxThreads) { this.maxThreads = maxThreads; }
- public int getMaxThreads() { return maxThreads; }
-
-
- /**
- * Priority of the acceptor and poller threads.
- */
- protected int threadPriority = Thread.NORM_PRIORITY;
- public void setThreadPriority(int threadPriority) { this.threadPriority =
threadPriority; }
- public int getThreadPriority() { return threadPriority; }
-
-
- /**
- * Size of the socket poller.
- */
- protected int pollerSize = (org.apache.tomcat.util.Constants.LOW_MEMORY) ? 128 : (32
* 1024);
- public void setPollerSize(int pollerSize) { this.pollerSize = pollerSize; }
- public int getPollerSize() { return pollerSize; }
-
-
- /**
- * Keep-Alive timeout.
- */
- protected int keepAliveTimeout = -1;
- public int getKeepAliveTimeout() { return keepAliveTimeout; }
- public void setKeepAliveTimeout(int keepAliveTimeout) { this.keepAliveTimeout =
keepAliveTimeout; }
-
-
- /**
- * Server socket port.
- */
- protected int port;
- public int getPort() { return port; }
- public void setPort(int port ) { this.port=port; }
-
-
- /**
- * Address for the server socket.
- */
- protected InetAddress address;
- public InetAddress getAddress() { return address; }
- public void setAddress(InetAddress address) { this.address = address; }
-
-
- /**
- * Handling of accepted sockets.
- */
- protected Handler handler = null;
- public void setHandler(Handler handler ) { this.handler = handler; }
- public Handler getHandler() { return handler; }
-
-
- /**
- * Allows the server developer to specify the backlog that
- * should be used for server sockets. By default, this value
- * is 100.
- */
- protected int backlog = 100;
- public void setBacklog(int backlog) { if (backlog > 0) this.backlog = backlog; }
- public int getBacklog() { return backlog; }
-
-
- /**
- * Socket TCP no delay.
- */
- protected boolean tcpNoDelay = false;
- public boolean getTcpNoDelay() { return tcpNoDelay; }
- public void setTcpNoDelay(boolean tcpNoDelay) { this.tcpNoDelay = tcpNoDelay; }
-
-
- /**
- * Socket linger.
- */
- protected int soLinger = 100;
- public int getSoLinger() { return soLinger; }
- public void setSoLinger(int soLinger) { this.soLinger = soLinger; }
-
-
- /**
- * Socket timeout.
- */
- protected int soTimeout = -1;
- public int getSoTimeout() { return soTimeout; }
- public void setSoTimeout(int soTimeout) { this.soTimeout = soTimeout; }
-
-
- /**
- * The default is true - the created threads will be
- * in daemon mode. If set to false, the control thread
- * will not be daemon - and will keep the process alive.
- */
- protected boolean daemon = true;
- public void setDaemon(boolean b) { daemon = b; }
- public boolean getDaemon() { return daemon; }
-
-
- /**
- * Name of the thread pool, which will be used for naming child threads.
- */
- protected String name = "TP";
- public void setName(String name) { this.name = name; }
- public String getName() { return name; }
-
-
- /**
- * Server socket factory.
- */
- protected ServerSocketFactory serverSocketFactory = null;
- public void setServerSocketFactory(ServerSocketFactory factory) {
this.serverSocketFactory = factory; }
- public ServerSocketFactory getServerSocketFactory() { return serverSocketFactory; }
-
-
- /**
- * The socket poller used for event support.
- */
- protected Poller eventPoller = null;
- public Poller getEventPoller() {
- return eventPoller;
- }
-
-
- public boolean isRunning() {
- return running;
- }
-
- public boolean isPaused() {
- return paused;
- }
-
- public int getCurrentThreadCount() {
- return curThreads;
- }
-
- public int getCurrentThreadsBusy() {
- return workers!=null?curThreads - workers.size():0;
- }
-
-
- // ------------------------------------------------ Handler Inner Interface
-
-
- /**
- * Bare bones interface used for socket processing. Per thread data is to be
- * stored in the ThreadWithAttributes extra folders, or alternately in
- * thread local fields.
- */
- public interface Handler {
- public enum SocketState {
- OPEN, CLOSED, LONG
- }
- public SocketState process(Socket socket);
- public SocketState event(Socket socket, SocketStatus status);
- }
-
-
- // --------------------------------------------------- Acceptor Inner Class
-
-
- /**
- * Server socket acceptor thread.
- */
- protected class Acceptor implements Runnable {
-
-
- /**
- * The background thread that listens for incoming TCP/IP connections and
- * hands them off to an appropriate processor.
- */
- public void run() {
-
- // Loop until we receive a shutdown command
- while (running) {
-
- // Loop if endpoint is paused
- while (paused) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Ignore
- }
- }
-
- // Accept the next incoming connection from the server socket
- try {
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
- serverSocketFactory.initSocket(socket);
- // Hand this socket off to an appropriate processor
- if (!processSocket(socket)) {
- // Close socket right away
- try { socket.close(); } catch (IOException e) { }
- }
- }catch ( IOException x ) {
- if ( running )
log.error(sm.getString("endpoint.accept.fail"), x);
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.accept.fail"), t);
- }
-
- // The processor will recycle itself when it finishes
-
- }
-
- }
-
- }
-
-
- // ------------------------------------------------- SocketInfo Inner Class
-
-
- /**
- * Socket list class, used to avoid using a possibly large amount of objects
- * with very little actual use.
- */
- public static class SocketInfo {
- public static final int RESUME = 4;
- public static final int WAKEUP = 8;
- public Socket socket;
- public int timeout;
- public int flags;
- public boolean resume() {
- return (flags & RESUME) == RESUME;
- }
- public boolean wakeup() {
- return (flags & WAKEUP) == WAKEUP;
- }
- public static int merge(int flag1, int flag2) {
- return ((flag1 & RESUME) | (flag2 & RESUME))
- | ((flag1 & WAKEUP) & (flag2 & WAKEUP));
- }
- }
-
-
- // --------------------------------------------- SocketTimeouts Inner Class
-
-
- /**
- * Socket list class, used to avoid using a possibly large amount of objects
- * with very little actual use.
- */
- public class SocketTimeouts {
- protected int size;
-
- protected Socket[] sockets;
- protected long[] timeouts;
- protected int pos = 0;
-
- public SocketTimeouts(int size) {
- this.size = 0;
- sockets = new Socket[size];
- timeouts = new long[size];
- }
-
- public void add(Socket socket, long timeout) {
- sockets[size] = socket;
- timeouts[size] = timeout;
- size++;
- }
-
- public boolean remove(Socket socket) {
- for (int i = 0; i < size; i++) {
- if (sockets[i] == socket) {
- sockets[i] = sockets[size - 1];
- timeouts[i] = timeouts[size - 1];
- size--;
- return true;
- }
- }
- return false;
- }
-
- public Socket check(long date) {
- while (pos < size) {
- if (date >= timeouts[pos]) {
- Socket result = sockets[pos];
- sockets[pos] = sockets[size - 1];
- timeouts[pos] = timeouts[size - 1];
- size--;
- return result;
- }
- pos++;
- }
- pos = 0;
- return null;
- }
-
- }
-
-
- // ------------------------------------------------- SocketList Inner Class
-
-
- /**
- * Socket list class, used to avoid using a possibly large amount of objects
- * with very little actual use.
- */
- public class SocketList {
- protected int size;
- protected int pos;
-
- protected Socket[] sockets;
- protected int[] timeouts;
- protected int[] flags;
-
- protected SocketInfo info = new SocketInfo();
-
- public SocketList(int size) {
- this.size = 0;
- pos = 0;
- sockets = new Socket[size];
- timeouts = new int[size];
- flags = new int[size];
- }
-
- public int size() {
- return this.size;
- }
-
- public SocketInfo get() {
- if (pos == size) {
- return null;
- } else {
- info.socket = sockets[pos];
- info.timeout = timeouts[pos];
- info.flags = flags[pos];
- pos++;
- return info;
- }
- }
-
- public void clear() {
- size = 0;
- pos = 0;
- }
-
- public boolean add(Socket socket, int timeout, int flag) {
- if (size == sockets.length) {
- return false;
- } else {
- for (int i = 0; i < size; i++) {
- if (sockets[i] == socket) {
- flags[i] = SocketInfo.merge(flags[i], flag);
- return true;
- }
- }
- sockets[size] = socket;
- timeouts[size] = timeout;
- flags[size] = flag;
- size++;
- return true;
- }
- }
-
- public void duplicate(SocketList copy) {
- copy.size = size;
- copy.pos = pos;
- System.arraycopy(sockets, 0, copy.sockets, 0, size);
- System.arraycopy(timeouts, 0, copy.timeouts, 0, size);
- System.arraycopy(flags, 0, copy.flags, 0, size);
- }
-
- }
-
-
- // ------------------------------------------- SocketProcessor Inner Class
-
-
- /**
- * This class is the equivalent of the Worker, but will simply use in an
- * external Executor thread pool.
- */
- protected class SocketProcessor implements Runnable {
-
- protected Socket socket = null;
-
- public SocketProcessor(Socket socket) {
- this.socket = socket;
- }
-
- public void run() {
-
- // Process the request from this socket
- if (!setSocketOptions(socket) || (handler.process(socket) ==
Handler.SocketState.CLOSED)) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- }
-
- // Finish up this request
- socket = null;
-
- }
-
- }
-
-
- // --------------------------------------- SocketEventProcessor Inner Class
-
-
- /**
- * This class is the equivalent of the Worker, but will simply use in an
- * external Executor thread pool.
- */
- protected class SocketEventProcessor implements Runnable {
-
- protected Socket socket = null;
- protected SocketStatus status = null;
-
- public SocketEventProcessor(Socket socket, SocketStatus status) {
- this.socket = socket;
- this.status = status;
- }
-
- public void run() {
-
- Handler.SocketState socketState = handler.event(socket, status);
- if (socketState == Handler.SocketState.CLOSED) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- } else if (socketState == Handler.SocketState.OPEN) {
- // Process the keepalive after the event processing
- // This is the main behavior difference with endpoint with pollers,
which
- // will add the socket to the poller
- if (handler.process(socket) == Handler.SocketState.CLOSED) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- }
- }
- socket = null;
-
- }
-
- }
-
-
- // ----------------------------------------------------- Poller Inner Class
-
-
- /**
- * Poller class.
- */
- public class Poller implements Runnable {
-
- /**
- * List of sockets to be added to the poller.
- */
- protected SocketList addList = null;
-
- /**
- * List of sockets to be added to the poller.
- */
- protected SocketList localAddList = null;
-
- /**
- * Structure used for storing timeouts.
- */
- protected SocketTimeouts timeouts = null;
-
-
- /**
- * Last run of maintain. Maintain will run usually every 5s.
- */
- protected long lastMaintain = System.currentTimeMillis();
-
-
- /**
- * Amount of connections inside this poller.
- */
- protected int connectionCount = 0;
- public int getConnectionCount() { return connectionCount; }
-
- public Poller() {
- }
-
- /**
- * Create the poller. The java.io poller only deals with timeouts.
- */
- protected void init() {
-
- timeouts = new SocketTimeouts(pollerSize);
-
- connectionCount = 0;
- addList = new SocketList(pollerSize);
- localAddList = new SocketList(pollerSize);
-
- }
-
- /**
- * Destroy the poller.
- */
- protected void destroy() {
- // Wait for pollerTime before doing anything, so that the poller threads
- // exit, otherwise parallel destruction of sockets which are still
- // in the poller can cause problems
- try {
- synchronized (this) {
- this.wait(2);
- }
- } catch (InterruptedException e) {
- // Ignore
- }
- // Close all sockets in the add queue
- SocketInfo info = addList.get();
- while (info != null) {
- if (!processSocket(info.socket, SocketStatus.STOP)) {
- try { info.socket.close(); } catch (IOException e) { }
- }
- info = addList.get();
- }
- addList.clear();
- // Close all sockets still in the poller
- long future = System.currentTimeMillis() + Integer.MAX_VALUE;
- Socket socket = timeouts.check(future);
- while (socket != null) {
- if (!processSocket(socket, SocketStatus.TIMEOUT)) {
- try { socket.close(); } catch (IOException e) { }
- }
- socket = timeouts.check(future);
- }
- connectionCount = 0;
- }
-
- /**
- * Add specified socket and associated pool to the poller. The socket will
- * be added to a temporary array, and polled first after a maximum amount
- * of time equal to pollTime (in most cases, latency will be much lower,
- * however).
- *
- * @param socket to add to the poller
- */
- public void add(Socket socket, int timeout, boolean resume, boolean wakeup) {
- if (timeout < 0) {
- timeout = keepAliveTimeout;
- }
- if (timeout < 0) {
- timeout = soTimeout;
- }
- if (timeout <= 0) {
- // Always put a timeout in
- timeout = Integer.MAX_VALUE;
- }
- boolean ok = false;
- synchronized (this) {
- // Add socket to the list. Newly added sockets will wait
- // at most for pollTime before being polled
- if (addList.add(socket, timeout, (resume ? SocketInfo.RESUME : 0)
- | (wakeup ? SocketInfo.WAKEUP : 0))) {
- ok = true;
- this.notify();
- }
- }
- if (!ok) {
- // Can't do anything: close the socket right away
- if (!processSocket(socket, SocketStatus.ERROR)) {
- try { socket.close(); } catch (IOException e) { }
- }
- }
- }
-
- /**
- * Timeout checks.
- */
- protected void maintain() {
-
- long date = System.currentTimeMillis();
- // Maintain runs at most once every 5s, although it will likely get called
more
- if ((date - lastMaintain) < 5000L) {
- return;
- } else {
- lastMaintain = date;
- }
- Socket socket = timeouts.check(date);
- while (socket != null) {
- if (!processSocket(socket, SocketStatus.TIMEOUT)) {
- try { socket.close(); } catch (IOException e) { }
- }
- socket = timeouts.check(date);
- }
-
- }
-
- /**
- * The background thread that listens for incoming TCP/IP connections and
- * hands them off to an appropriate processor.
- */
- public void run() {
-
- int maintain = 0;
- // Loop until we receive a shutdown command
- while (running) {
-
- // Loop if endpoint is paused
- while (paused) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Ignore
- }
- }
- // Check timeouts for suspended connections if the poller is empty
- while (connectionCount < 1 && addList.size() < 1) {
- // Reset maintain time.
- try {
- if (soTimeout > 0 && running) {
- maintain();
- }
- synchronized (this) {
- this.wait(10000);
- }
- } catch (InterruptedException e) {
- // Ignore
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.maintain.error"), t);
- }
- }
-
- try {
-
- // Add sockets which are waiting to the poller
- if (addList.size() > 0) {
- synchronized (this) {
- // Duplicate to another list, so that the syncing is minimal
- addList.duplicate(localAddList);
- addList.clear();
- }
- SocketInfo info = localAddList.get();
- while (info != null) {
- if (info.wakeup()) {
- // Resume event if socket is present in the poller
- if (timeouts.remove(info.socket)) {
- if (info.resume()) {
- if (!processSocket(info.socket,
SocketStatus.OPEN_CALLBACK)) {
- try { info.socket.close(); } catch
(IOException e) { }
- }
- } else {
- timeouts.add(info.socket,
System.currentTimeMillis() + info.timeout);
- }
- }
- } else {
- if (info.resume()) {
- timeouts.remove(info.socket);
- if (!processSocket(info.socket,
SocketStatus.OPEN_CALLBACK)) {
- try { info.socket.close(); } catch (IOException
e) { }
- }
- } else {
- timeouts.add(info.socket, System.currentTimeMillis()
+ info.timeout);
- }
- }
- info = localAddList.get();
- }
- }
-
- try {
- Thread.sleep(2);
- } catch (InterruptedException e) {
- // Ignore
- }
-
- // Process socket timeouts
- if (soTimeout > 0 && maintain++ > 1000 &&
running) {
- maintain = 0;
- maintain();
- }
-
- } catch (Throwable t) {
- if (maintain == 0) {
- log.error(sm.getString("endpoint.maintain.error"), t);
- } else {
- log.error(sm.getString("endpoint.poll.error"), t);
- }
- }
-
- }
-
- synchronized (this) {
- this.notifyAll();
- }
-
- }
-
- }
-
-
- // ----------------------------------------------------- Worker Inner Class
-
-
- protected class Worker implements Runnable {
-
- protected Thread thread = null;
- protected boolean available = false;
- protected Socket socket = null;
- protected SocketStatus status = null;
-
-
- /**
- * Process an incoming TCP/IP connection on the specified socket. Any
- * exception that occurs during processing must be logged and swallowed.
- * <b>NOTE</b>: This method is called from our Connector's
thread. We
- * must assign it to our own thread so that multiple simultaneous
- * requests can be handled.
- *
- * @param socket TCP socket to process
- */
- protected synchronized void assign(Socket socket) {
-
- // Wait for the Processor to get the previous Socket
- while (available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
-
- // Store the newly available Socket and notify our thread
- this.socket = socket;
- this.status = null;
- available = true;
- notifyAll();
-
- }
-
-
- protected synchronized void assign(Socket socket, SocketStatus status) {
-
- // Wait for the Processor to get the previous Socket
- while (available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
-
- // Store the newly available Socket and notify our thread
- this.socket = socket;
- this.status = status;
- available = true;
- notifyAll();
-
- }
-
-
- /**
- * Await a newly assigned Socket from our Connector, or
<code>null</code>
- * if we are supposed to shut down.
- */
- private synchronized Socket await() {
-
- // Wait for the Connector to provide a new Socket
- while (!available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
-
- // Notify the Connector that we have received this Socket
- Socket socket = this.socket;
- available = false;
- notifyAll();
-
- return (socket);
-
- }
-
-
-
- /**
- * The background thread that listens for incoming TCP/IP connections and
- * hands them off to an appropriate processor.
- */
- public void run() {
-
- // Process requests until we receive a shutdown signal
- while (running) {
-
- // Wait for the next socket to be assigned
- Socket socket = await();
- if (socket == null)
- continue;
-
- // Process the request from this socket
- if (status != null){
- Handler.SocketState socketState = handler.event(socket, status);
- if (socketState == Handler.SocketState.CLOSED) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- } else if (socketState == Handler.SocketState.OPEN) {
- // Process the keepalive after the event processing
- // This is the main behavior difference with endpoint with
pollers, which
- // will add the socket to the poller
- if (handler.process(socket) == Handler.SocketState.CLOSED) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- }
- }
- } else if ((status == null) && (!setSocketOptions(socket) ||
(handler.process(socket) == Handler.SocketState.CLOSED))) {
- // Close socket
- try { socket.close(); } catch (IOException e) { }
- }
-
- // Finish up this request
- recycleWorkerThread(this);
-
- }
-
- }
-
-
- /**
- * Start the background processing thread.
- */
- public void start() {
- thread = new Thread(this);
- thread.setName(getName() + "-" + (++curThreads));
- thread.setDaemon(true);
- thread.start();
- }
-
-
- }
-
-
- // -------------------- Public methods --------------------
-
- public void init()
- throws Exception {
-
- if (initialized)
- return;
-
- // Initialize thread count defaults for acceptor
- if (acceptorThreadCount == 0) {
- acceptorThreadCount = 1;
- }
- if (serverSocketFactory == null) {
- serverSocketFactory = ServerSocketFactory.getDefault();
- }
- if (serverSocket == null) {
- try {
- if (address == null) {
- serverSocket = serverSocketFactory.createSocket(port, backlog);
- } else {
- serverSocket = serverSocketFactory.createSocket(port, backlog,
address);
- }
- } catch (BindException be) {
- if (address == null) {
- throw new BindException(be.getMessage() + "<null>:" +
port);
- } else {
- throw new BindException(be.getMessage() + " " +
- address.toString() + ":" + port);
- }
- }
- }
- //if( serverTimeout >= 0 )
- // serverSocket.setSoTimeout( serverTimeout );
-
- initialized = true;
-
- }
-
- public void start()
- throws Exception {
- // Initialize socket if not done before
- if (!initialized) {
- init();
- }
- if (!running) {
- running = true;
- paused = false;
-
- // Create worker collection
- if (executor == null) {
- workers = new WorkerStack(maxThreads);
- }
-
- // Start event poller thread
- eventPoller = new Poller();
- eventPoller.init();
- Thread pollerThread = new Thread(eventPoller, getName() +
"-Poller");
- pollerThread.setPriority(threadPriority);
- pollerThread.setDaemon(true);
- pollerThread.start();
-
- // Start acceptor threads
- for (int i = 0; i < acceptorThreadCount; i++) {
- Thread acceptorThread = new Thread(new Acceptor(), getName() +
"-Acceptor-" + i);
- acceptorThread.setPriority(threadPriority);
- acceptorThread.setDaemon(daemon);
- acceptorThread.start();
- }
- }
- }
-
- public void pause() {
- if (running && !paused) {
- paused = true;
- unlockAccept();
- }
- }
-
- public void resume() {
- if (running) {
- paused = false;
- }
- }
-
- public void stop() {
- if (running) {
- running = false;
- unlockAccept();
- eventPoller.destroy();
- eventPoller = null;
- }
- }
-
- /**
- * Deallocate APR memory pools, and close server socket.
- */
- public void destroy() throws Exception {
- if (running) {
- stop();
- }
- if (serverSocket != null) {
- try {
- if (serverSocket != null)
- serverSocket.close();
- } catch (Exception e) {
- log.error(sm.getString("endpoint.err.close"), e);
- }
- serverSocket = null;
- }
- initialized = false ;
- }
-
-
- /**
- * Unlock the accept by using a local connection.
- */
- protected void unlockAccept() {
- Socket s = null;
- try {
- // Need to create a connection to unlock the accept();
- if (address == null) {
- s = new Socket("localhost", port);
- } else {
- s = new Socket(address, port);
- // setting soLinger to a small value will help shutdown the
- // connection quicker
- s.setSoLinger(true, 0);
- }
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("endpoint.debug.unlock", "" +
port), e);
- }
- } finally {
- if (s != null) {
- try {
- s.close();
- } catch (Exception e) {
- // Ignore
- }
- }
- }
- }
-
-
- /**
- * Set the options for the current socket.
- */
- protected boolean setSocketOptions(Socket socket) {
- // Process the connection
- int step = 1;
- try {
-
- // 1: Set socket options: timeout, linger, etc
- if (soLinger >= 0) {
- socket.setSoLinger(true, soLinger);
- }
- if (tcpNoDelay) {
- socket.setTcpNoDelay(tcpNoDelay);
- }
- if (soTimeout > 0) {
- socket.setSoTimeout(soTimeout);
- }
-
- // 2: SSL handshake
- step = 2;
- serverSocketFactory.handshake(socket);
-
- } catch (Throwable t) {
- if (log.isDebugEnabled()) {
- if (step == 2) {
- log.debug(sm.getString("endpoint.err.handshake"), t);
- } else {
- log.debug(sm.getString("endpoint.err.unexpected"), t);
- }
- }
- // Tell to close the socket
- return false;
- }
- return true;
- }
-
-
- /**
- * Create (or allocate) and return an available processor for use in
- * processing a specific HTTP request, if possible. If the maximum
- * allowed processors have already been created and are in use, return
- * <code>null</code> instead.
- */
- protected Worker createWorkerThread() {
-
- synchronized (workers) {
- if (workers.size() > 0) {
- curThreadsBusy++;
- return workers.pop();
- }
- if ((maxThreads > 0) && (curThreads < maxThreads)) {
- curThreadsBusy++;
- if (curThreadsBusy == maxThreads) {
- log.info(sm.getString("endpoint.info.maxThreads",
- Integer.toString(maxThreads), address,
- Integer.toString(port)));
- }
- return (newWorkerThread());
- } else {
- if (maxThreads < 0) {
- curThreadsBusy++;
- return (newWorkerThread());
- } else {
- return (null);
- }
- }
- }
-
- }
-
-
- /**
- * Create and return a new processor suitable for processing HTTP
- * requests and returning the corresponding responses.
- */
- protected Worker newWorkerThread() {
-
- Worker workerThread = new Worker();
- workerThread.start();
- return (workerThread);
-
- }
-
-
- /**
- * Return a new worker thread, and block while to worker is available.
- */
- protected Worker getWorkerThread() {
- // Allocate a new worker thread
- Worker workerThread = createWorkerThread();
- if (org.apache.tomcat.util.net.Constants.WAIT_FOR_THREAD
- || org.apache.tomcat.util.Constants.LOW_MEMORY) {
- while (workerThread == null) {
- try {
- synchronized (workers) {
- workers.wait();
- }
- } catch (InterruptedException e) {
- // Ignore
- }
- workerThread = createWorkerThread();
- }
- }
- return workerThread;
- }
-
-
- /**
- * Recycle the specified Processor so that it can be used again.
- *
- * @param workerThread The processor to be recycled
- */
- protected void recycleWorkerThread(Worker workerThread) {
- synchronized (workers) {
- workers.push(workerThread);
- curThreadsBusy--;
- workers.notify();
- }
- }
-
-
- /**
- * Process given socket.
- */
- protected boolean processSocket(Socket socket) {
- try {
- if (executor == null) {
- Worker worker = getWorkerThread();
- if (worker != null) {
- worker.assign(socket);
- } else {
- return false;
- }
- } else {
- executor.execute(new SocketProcessor(socket));
- }
- } catch (Throwable t) {
- // This means we got an OOM or similar creating a thread, or that
- // the pool and its queue are full
- log.error(sm.getString("endpoint.process.fail"), t);
- return false;
- }
- return true;
- }
-
-
- /**
- * Process given socket for an event.
- */
- protected boolean processSocket(Socket socket, SocketStatus status) {
- try {
- if (executor == null) {
- Worker worker = getWorkerThread();
- if (worker != null) {
- worker.assign(socket, status);
- } else {
- return false;
- }
- } else {
- executor.execute(new SocketEventProcessor(socket, status));
- }
- } catch (Throwable t) {
- // This means we got an OOM or similar creating a thread, or that
- // the pool and its queue are full
- log.error(sm.getString("endpoint.process.fail"), t);
- return false;
- }
- return true;
- }
-
-
- // ------------------------------------------------- WorkerStack Inner Class
-
-
- public class WorkerStack {
-
- protected Worker[] workers = null;
- protected int end = 0;
-
- public WorkerStack(int size) {
- workers = new Worker[size];
- }
-
- /**
- * Put the object into the queue.
- *
- * @param object the object to be appended to the queue (first element).
- */
- public void push(Worker worker) {
- workers[end++] = worker;
- }
-
- /**
- * Get the first object out of the queue. Return null if the queue
- * is empty.
- */
- public Worker pop() {
- if (end > 0) {
- return workers[--end];
- }
- return null;
- }
-
- /**
- * Get the first object out of the queue, Return null if the queue
- * is empty.
- */
- public Worker peek() {
- return workers[end];
- }
-
- /**
- * Is the queue empty?
- */
- public boolean isEmpty() {
- return (end == 0);
- }
-
- /**
- * How many elements are there in this queue?
- */
- public int size() {
- return (end);
- }
- }
-
-}
Modified: trunk/java/org/apache/tomcat/util/net/SSLImplementation.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/SSLImplementation.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/SSLImplementation.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -37,12 +37,8 @@
private static org.jboss.logging.Logger logger = org.jboss.logging.Logger
.getLogger(SSLImplementation.class);
- // The default implementations in our search path
- private static final String JSSEImplementationClass =
"org.apache.tomcat.util.net.jsse.JSSEImplementation";
+ private static final String[] implementations = {
"org.apache.tomcat.util.net.jsse.NioJSSEImplementation" };
- private static final String[] implementations = { JSSEImplementationClass,
- "org.apache.tomcat.util.net.jsse.NioJSSEImplementation" };
-
/**
* @return the default implementation of {@code SSLImplementation}
* @throws ClassNotFoundException
@@ -74,13 +70,6 @@
return getInstance();
try {
- // Workaround for the J2SE 1.4.x classloading problem (under
- // Solaris).
- // Class.forName(..) fails without creating class using new.
- // This is an ugly workaround.
- if (JSSEImplementationClass.equals(className)) {
- return new org.apache.tomcat.util.net.jsse.JSSEImplementation();
- }
Class<?> clazz = Class.forName(className);
return (SSLImplementation) clazz.newInstance();
} catch (Exception e) {
@@ -97,24 +86,12 @@
abstract public String getImplementationName();
/**
- * @return a new instance of {@link ServerSocketFactory}
- */
- abstract public ServerSocketFactory getServerSocketFactory();
-
- /**
*
* @return a new instance of {@link NioJSSESocketChannelFactory}
*/
public abstract NioJSSESocketChannelFactory getServerSocketChannelFactory();
/**
- * Return a {@link SSLSupport} attached to the socket
- * @param sock
- * @return a {@link SSLSupport} attached to the socket
- */
- abstract public SSLSupport getSSLSupport(Socket sock);
-
- /**
* @param channel
* @return the {@link SSLSupport} attached to this channel
*/
Deleted: trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package
org.apache.tomcat.util.net;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Hashtable;
-
-/**
- * This class creates server sockets. It may be subclassed by other
- * factories, which create particular types of server sockets. This
- * provides a general framework for the addition of public socket-level
- * functionality. It it is the server side analogue of a socket factory,
- * and similarly provides a way to capture a variety of policies related
- * to the sockets being constructed.
- *
- * <P> Like socket factories, Server Socket factory instances have two
- * categories of methods. First are methods used to create sockets.
- * Second are methods which set properties used in the production of
- * sockets, such as networking options. There is also an environment
- * specific default server socket factory; frameworks will often use
- * their own customized factory.
- *
- * <P><hr><em> It may be desirable to move this interface into the
- * <b>java.net</b> package, so that is not an extension but the preferred
- * interface. Should this be serializable, making it a JavaBean which can
- * be saved along with its networking configuration?
- * </em>
- *
- * @author db(a)eng.sun.com
- * @author Harish Prabandham
- */
-public abstract class ServerSocketFactory implements Cloneable {
-
- //
- // NOTE: JDK 1.1 bug in class GC, this can get collected
- // even though it's always accessible via getDefault().
- //
-
- private static ServerSocketFactory theFactory;
- protected Hashtable attributes=new Hashtable();
-
- /**
- * Constructor is used only by subclasses.
- */
-
- protected ServerSocketFactory () {
- /* NOTHING */
- }
-
- /** General mechanism to pass attributes from the
- * ServerConnector to the socket factory.
- *
- * Note that the "prefered" mechanism is to
- * use bean setters and explicit methods, but
- * this allows easy configuration via server.xml
- * or simple Properties
- */
- public void setAttribute( String name, Object value ) {
- if( name!=null && value !=null)
- attributes.put( name, value );
- }
-
- /**
- * Returns a copy of the environment's default socket factory.
- */
- public static synchronized ServerSocketFactory getDefault () {
- //
- // optimize typical case: no synch needed
- //
-
- if (theFactory == null) {
- //
- // Different implementations of this method could
- // work rather differently. For example, driving
- // this from a system property, or using a different
- // implementation than JavaSoft's.
- //
-
- theFactory = new DefaultServerSocketFactory ();
- }
-
- try {
- return (ServerSocketFactory) theFactory.clone ();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException (e.getMessage ());
- }
- }
-
- /**
- * Returns a server socket which uses all network interfaces on
- * the host, and is bound to a the specified port. The socket is
- * configured with the socket options (such as accept timeout)
- * given to this factory.
- *
- * @param port the port to listen to
- * @exception IOException for networking errors
- * @exception InstantiationException for construction errors
- */
- public abstract ServerSocket createSocket (int port)
- throws IOException, InstantiationException;
-
- /**
- * Returns a server socket which uses all network interfaces on
- * the host, is bound to a the specified port, and uses the
- * specified connection backlog. The socket is configured with
- * the socket options (such as accept timeout) given to this factory.
- *
- * @param port the port to listen to
- * @param backlog how many connections are queued
- * @exception IOException for networking errors
- * @exception InstantiationException for construction errors
- */
-
- public abstract ServerSocket createSocket (int port, int backlog)
- throws IOException, InstantiationException;
-
- /**
- * Returns a server socket which uses only the specified network
- * interface on the local host, is bound to a the specified port,
- * and uses the specified connection backlog. The socket is configured
- * with the socket options (such as accept timeout) given to this factory.
- *
- * @param port the port to listen to
- * @param backlog how many connections are queued
- * @param ifAddress the network interface address to use
- * @exception IOException for networking errors
- * @exception InstantiationException for construction errors
- */
-
- public abstract ServerSocket createSocket (int port,
- int backlog, InetAddress ifAddress)
- throws IOException, InstantiationException;
-
- public void initSocket( Socket s ) {
- }
-
- /**
- Wrapper function for accept(). This allows us to trap and
- translate exceptions if necessary
-
- @exception IOException;
- */
- public abstract Socket acceptSocket(ServerSocket socket)
- throws IOException;
-
- /**
- Extra function to initiate the handshake. Sometimes necessary
- for SSL
-
- @exception IOException;
- */
- public abstract void handshake(Socket sock)
- throws IOException;
-}
-
Deleted: trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.util.net.jsse;
-
-import java.net.Socket;
-
-import javax.net.ssl.SSLSocket;
-
-import org.apache.tomcat.util.net.SSLSupport;
-import org.apache.tomcat.util.net.ServerSocketFactory;
-import javax.net.ssl.SSLSession;
-
-/**
- * Factory interface to construct components based on the JSSE version
- * in use.
- *
- * @author Bill Barker
- * @author Filip Hanik
- */
-
-public class JSSEFactory {
-
- /**
- * Returns the ServerSocketFactory to use.
- */
- public ServerSocketFactory getSocketFactory() {
- return new JSSESocketFactory();
- }
-
- /**
- * returns the SSLSupport attached to this socket.
- */
- public SSLSupport getSSLSupport(Socket socket) {
- return new JSSESupport((SSLSocket)socket);
- }
-
- public SSLSupport getSSLSupport(SSLSession session) {
- return new JSSESupport(session);
- }
-
-};
Deleted: trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java 2012-06-13 08:50:17
UTC (rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java 2012-06-14 14:11:34
UTC (rev 2042)
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
License.
- * You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.apache.tomcat.util.net.jsse;
-
-import java.net.Socket;
-
-import org.apache.tomcat.util.net.NioChannel;
-import org.apache.tomcat.util.net.SSLImplementation;
-import org.apache.tomcat.util.net.SSLSupport;
-import org.apache.tomcat.util.net.ServerSocketFactory;
-import javax.net.ssl.SSLSession;
-
-/**
- * {@code JSSEImplementation}
- * <p>
- * Concrete implementation class for JSSE
- * </p>
- *
- *
- * Created on Feb 22, 2012 at 12:53:14 PM
- *
- * @author EKR & <a href="mailto:nbenothm@redhat.com">Nabil
Benothman</a>
- */
-public class JSSEImplementation extends SSLImplementation {
- static final String SSLSocketClass = "javax.net.ssl.SSLSocket";
-
- static org.jboss.logging.Logger logger = org.jboss.logging.Logger
- .getLogger(JSSEImplementation.class);
-
- private JSSEFactory factory = null;
-
- /**
- * Create a new instance of {@code JSSEImplementation}
- *
- * @throws ClassNotFoundException
- */
- public JSSEImplementation() throws ClassNotFoundException {
- // Check to see if JSSE is floating around somewhere
- Class.forName(SSLSocketClass);
- factory = new JSSEFactory();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.tomcat.util.net.SSLImplementation#getImplementationName()
- */
- public String getImplementationName() {
- return "JSSE";
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getServerSocketFactory()
- */
- public ServerSocketFactory getServerSocketFactory() {
- ServerSocketFactory ssf = factory.getSocketFactory();
- return ssf;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getSSLSupport(java.net.Socket
- * )
- */
- public SSLSupport getSSLSupport(Socket s) {
- SSLSupport ssls = factory.getSSLSupport(s);
- return ssls;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- *
org.apache.tomcat.util.net.SSLImplementation#getSSLSupport(javax.net.
- * ssl.SSLSession)
- */
- public SSLSupport getSSLSupport(SSLSession session) {
- SSLSupport ssls = factory.getSSLSupport(session);
- return ssls;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getServerSocketChannelFactory
- * ()
- */
- @Override
- public NioJSSESocketChannelFactory getServerSocketChannelFactory() {
- throw new RuntimeException("Not supported for class " +
NioJSSESocketChannelFactory.class.getName());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getSSLSupport(org.apache
- * .tomcat.util.net.NioChannel)
- */
- @Override
- public SSLSupport getSSLSupport(NioChannel channel) {
- throw new RuntimeException("Not supported for class " +
NioChannel.class.getName());
- }
-
-}
\ No newline at end of file
Deleted: trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2012-06-13 08:50:17
UTC (rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2012-06-14 14:11:34
UTC (rev 2042)
@@ -1,812 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.util.net.jsse;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.cert.CRL;
-import java.security.cert.CRLException;
-import java.security.cert.CertPathParameters;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreParameters;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CollectionCertStoreParameters;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.X509CertSelector;
-import java.util.Collection;
-import java.util.Locale;
-import java.util.Vector;
-
-import javax.net.ssl.CertPathTrustManagerParameters;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509KeyManager;
-
-import org.apache.tomcat.util.res.StringManager;
-
-/*
- 1. Make the JSSE's jars available, either as an installed
- extension (copy them into jre/lib/ext) or by adding
- them to the Tomcat classpath.
- 2. keytool -genkey -alias tomcat -keyalg RSA
- Use "changeit" as password ( this is the default we use )
- */
-
-/**
- * SSL server socket factory. It _requires_ a valid RSA key and
- * JSSE.
- *
- * @author Harish Prabandham
- * @author Costin Manolache
- * @author Stefan Freyr Stefansson
- * @author EKR -- renamed to JSSESocketFactory
- * @author Jan Luehe
- * @author Bill Barker
- */
-public class JSSESocketFactory
- extends org.apache.tomcat.util.net.ServerSocketFactory {
-
- private static StringManager sm =
- StringManager.getManager("org.apache.tomcat.util.net.jsse.res");
- private static final boolean RFC_5746_SUPPORTED;
- // defaults
- static String defaultProtocol = "TLS";
- static boolean defaultClientAuth = false;
- static String defaultKeystoreType = "JKS";
- private static final String defaultKeystoreFile
- = System.getProperty("user.home") + "/.keystore";
- private static final String defaultKeyPass = "changeit";
- private static final int defaultSessionCacheSize = 0;
- private static final int defaultSessionTimeout = 86400;
-
- static org.jboss.logging.Logger log =
- org.jboss.logging.Logger.getLogger(JSSESocketFactory.class);
-
- static {
- boolean result = false;
- SSLContext context;
- try {
- context = SSLContext.getInstance("TLS");
- context.init(null, null, new SecureRandom());
- SSLServerSocketFactory ssf = context.getServerSocketFactory();
- String ciphers[] = ssf.getSupportedCipherSuites();
- for (String cipher : ciphers) {
- if ("TLS_EMPTY_RENEGOTIATION_INFO_SCSV".equals(cipher)) {
- result = true;
- break;
- }
- }
- } catch (NoSuchAlgorithmException e) {
- // Assume no RFC 5746 support
- } catch (KeyManagementException e) {
- // Assume no RFC 5746 support
- }
- RFC_5746_SUPPORTED = result;
- }
-
- protected boolean initialized;
- protected String clientAuth = "false";
- protected SSLServerSocketFactory sslProxy = null;
- protected String[] enabledCiphers;
- protected boolean allowUnsafeLegacyRenegotiation = false;
-
- /**
- * Flag to state that we require client authentication.
- */
- protected boolean requireClientAuth = false;
-
- /**
- * Flag to state that we would like client authentication.
- */
- protected boolean wantClientAuth = false;
-
-
- public JSSESocketFactory () {
- }
-
- public ServerSocket createSocket (int port)
- throws IOException
- {
- if (!initialized) init();
- ServerSocket socket = sslProxy.createServerSocket(port);
- initServerSocket(socket);
- return socket;
- }
-
- public ServerSocket createSocket (int port, int backlog)
- throws IOException
- {
- if (!initialized) init();
- ServerSocket socket = sslProxy.createServerSocket(port, backlog);
- initServerSocket(socket);
- return socket;
- }
-
- public ServerSocket createSocket (int port, int backlog,
- InetAddress ifAddress)
- throws IOException
- {
- if (!initialized) init();
- ServerSocket socket = sslProxy.createServerSocket(port, backlog,
- ifAddress);
- initServerSocket(socket);
- return socket;
- }
-
- public Socket acceptSocket(ServerSocket socket)
- throws IOException
- {
- SSLSocket asock = null;
- try {
- asock = (SSLSocket)socket.accept();
- } catch (SSLException e){
- throw new SocketException("SSL handshake error" + e.toString());
- }
- return asock;
- }
-
- public void handshake(Socket sock) throws IOException {
- // We do getSession instead of startHandshake() so we can call this multiple
times
- SSLSession session = ((SSLSocket)sock).getSession();
- if (session.getCipherSuite().equals("SSL_NULL_WITH_NULL_NULL"))
- throw new IOException("SSL handshake failed. Ciper suite in SSL Session
is SSL_NULL_WITH_NULL_NULL");
-
- if (!allowUnsafeLegacyRenegotiation && !RFC_5746_SUPPORTED) {
- // Prevent further handshakes by removing all cipher suites
- ((SSLSocket) sock).setEnabledCipherSuites(new String[0]);
- }
- }
-
- /*
- * Determines the SSL cipher suites to be enabled.
- *
- * @param requestedCiphers Comma-separated list of requested ciphers
- * @param supportedCiphers Array of supported ciphers
- *
- * @return Array of SSL cipher suites to be enabled, or null if none of the
- * requested ciphers are supported
- */
- protected String[] getEnabledCiphers(String requestedCiphers,
- String[] supportedCiphers) {
-
- String[] enabledCiphers = null;
-
- if (requestedCiphers != null) {
- Vector vec = null;
- String cipher = requestedCiphers;
- int index = requestedCiphers.indexOf(',');
- if (index != -1) {
- int fromIndex = 0;
- while (index != -1) {
- cipher = requestedCiphers.substring(fromIndex, index).trim();
- if (cipher.length() > 0) {
- /*
- * Check to see if the requested cipher is among the
- * supported ciphers, i.e., may be enabled
- */
- for (int i=0; supportedCiphers != null
- && i<supportedCiphers.length; i++) {
- if (supportedCiphers[i].equals(cipher)) {
- if (vec == null) {
- vec = new Vector();
- }
- vec.addElement(cipher);
- break;
- }
- }
- }
- fromIndex = index+1;
- index = requestedCiphers.indexOf(',', fromIndex);
- } // while
- cipher = requestedCiphers.substring(fromIndex);
- }
-
- if (cipher != null) {
- cipher = cipher.trim();
- if (cipher.length() > 0) {
- /*
- * Check to see if the requested cipher is among the
- * supported ciphers, i.e., may be enabled
- */
- for (int i=0; supportedCiphers != null
- && i<supportedCiphers.length; i++) {
- if (supportedCiphers[i].equals(cipher)) {
- if (vec == null) {
- vec = new Vector();
- }
- vec.addElement(cipher);
- break;
- }
- }
- }
- }
-
- if (vec != null) {
- enabledCiphers = new String[vec.size()];
- vec.copyInto(enabledCiphers);
- }
- } else {
- enabledCiphers = sslProxy.getDefaultCipherSuites();
- }
-
- return enabledCiphers;
- }
-
- /*
- * Gets the SSL server's keystore password.
- */
- protected String getKeystorePassword() {
- String keyPass = (String)attributes.get("keypass");
- if (keyPass == null) {
- keyPass = defaultKeyPass;
- }
- String keystorePass = (String)attributes.get("keystorePass");
- if (keystorePass == null) {
- keystorePass = keyPass;
- }
- return keystorePass;
- }
-
- /*
- * Gets the SSL server's keystore.
- */
- protected KeyStore getKeystore(String type, String provider, String pass)
- throws IOException {
-
- String keystoreFile = (String)attributes.get("keystore");
- if (keystoreFile == null)
- keystoreFile = defaultKeystoreFile;
-
- return getStore(type, provider, keystoreFile, pass);
- }
-
- /*
- * Gets the SSL server's truststore.
- */
- protected KeyStore getTrustStore(String keystoreType,
- String keystoreProvider) throws IOException {
- KeyStore trustStore = null;
-
- String truststoreFile = (String)attributes.get("truststoreFile");
- if(truststoreFile == null) {
- truststoreFile = System.getProperty("javax.net.ssl.trustStore");
- }
- if(log.isDebugEnabled()) {
- log.debug("Truststore = " + truststoreFile);
- }
- String truststorePassword = (String)attributes.get("truststorePass");
- if( truststorePassword == null) {
- truststorePassword =
System.getProperty("javax.net.ssl.trustStorePassword");
- }
- if(log.isDebugEnabled()) {
- log.debug("TrustPass = " + truststorePassword);
- }
- String truststoreType = (String)attributes.get("truststoreType");
- if( truststoreType == null) {
- truststoreType =
System.getProperty("javax.net.ssl.trustStoreType");
- }
- if(truststoreType == null) {
- truststoreType = keystoreType;
- }
- if(log.isDebugEnabled()) {
- log.debug("trustType = " + truststoreType);
- }
- String truststoreProvider =
- (String)attributes.get("truststoreProvider");
- if( truststoreProvider == null) {
- truststoreProvider =
- System.getProperty("javax.net.ssl.trustStoreProvider");
- }
- if (truststoreProvider == null) {
- truststoreProvider = keystoreProvider;
- }
- if(log.isDebugEnabled()) {
- log.debug("trustProvider = " + truststoreProvider);
- }
-
- if (truststoreFile != null){
- trustStore = getStore(truststoreType, truststoreProvider,
- truststoreFile, truststorePassword);
- }
-
- return trustStore;
- }
-
- /*
- * Gets the key- or truststore with the specified type, path, and password.
- */
- private KeyStore getStore(String type, String provider, String path,
- String pass) throws IOException {
-
- KeyStore ks = null;
- InputStream istream = null;
- try {
- if (provider == null) {
- ks = KeyStore.getInstance(type);
- } else {
- ks = KeyStore.getInstance(type, provider);
- }
- if(!("PKCS11".equalsIgnoreCase(type) ||
"".equalsIgnoreCase(path))) {
- File keyStoreFile = new File(path);
- if (!keyStoreFile.isAbsolute()) {
- keyStoreFile = new
File(System.getProperty("catalina.base"),
- path);
- }
- istream = new FileInputStream(keyStoreFile);
- }
-
- char[] storePass = null;
- if (pass != null) {
- storePass = pass.toCharArray();
- }
- ks.load(istream, storePass);
- } catch (FileNotFoundException fnfe) {
- log.error(sm.getString("jsse.keystore_load_failed", type, path,
- fnfe.getMessage()), fnfe);
- throw fnfe;
- } catch (IOException ioe) {
- log.error(sm.getString("jsse.keystore_load_failed", type, path,
- ioe.getMessage()), ioe);
- throw ioe;
- } catch(Exception ex) {
- String msg = sm.getString("jsse.keystore_load_failed", type, path,
- ex.getMessage());
- log.error(msg, ex);
- throw new IOException(msg);
- } finally {
- if (istream != null) {
- try {
- istream.close();
- } catch (IOException ioe) {
- // Do nothing
- }
- }
- }
-
- return ks;
- }
-
- /**
- * Reads the keystore and initializes the SSL socket factory.
- */
- void init() throws IOException {
- try {
-
- String clientAuthStr = (String) attributes.get("clientauth");
- if("true".equalsIgnoreCase(clientAuthStr) ||
- "yes".equalsIgnoreCase(clientAuthStr)) {
- requireClientAuth = true;
- } else if("want".equalsIgnoreCase(clientAuthStr)) {
- wantClientAuth = true;
- }
-
- // SSL protocol variant (e.g., TLS, SSL v3, etc.)
- String protocol = (String) attributes.get("protocol");
- if (protocol == null) {
- protocol = defaultProtocol;
- }
-
- // Certificate encoding algorithm (e.g., SunX509)
- String algorithm = (String) attributes.get("algorithm");
- if (algorithm == null) {
- algorithm = KeyManagerFactory.getDefaultAlgorithm();;
- }
-
- String keystoreType = (String) attributes.get("keystoreType");
- if (keystoreType == null) {
- keystoreType = defaultKeystoreType;
- }
-
- String keystoreProvider =
- (String) attributes.get("keystoreProvider");
-
- String trustAlgorithm =
- (String)attributes.get("truststoreAlgorithm");
- if( trustAlgorithm == null ) {
- trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
- }
-
- // Create and init SSLContext
- SSLContext context = (SSLContext) attributes.get("SSLContext");
- if (context == null) {
- context = SSLContext.getInstance(protocol);
- context.init(
- getKeyManagers(keystoreType, keystoreProvider,
- algorithm, (String)
attributes.get("keyAlias")),
- getTrustManagers(keystoreType, keystoreProvider,
- trustAlgorithm), new SecureRandom());
- }
-
- // Configure SSL session cache
- int sessionCacheSize;
- if (attributes.get("sessionCacheSize") != null) {
- sessionCacheSize = Integer.parseInt(
- (String)attributes.get("sessionCacheSize"));
- } else {
- sessionCacheSize = defaultSessionCacheSize;
- }
- int sessionCacheTimeout;
- if (attributes.get("sessionCacheTimeout") != null) {
- sessionCacheTimeout = Integer.parseInt(
- (String)attributes.get("sessionCacheTimeout"));
- } else {
- sessionCacheTimeout = defaultSessionTimeout;
- }
- SSLSessionContext sessionContext =
- context.getServerSessionContext();
- if (sessionContext != null) {
- sessionContext.setSessionCacheSize(sessionCacheSize);
- sessionContext.setSessionTimeout(sessionCacheTimeout);
- }
-
- // create proxy
- sslProxy = context.getServerSocketFactory();
-
- // Determine which cipher suites to enable
- String requestedCiphers = (String)attributes.get("ciphers");
- enabledCiphers = getEnabledCiphers(requestedCiphers,
- sslProxy.getSupportedCipherSuites());
-
- allowUnsafeLegacyRenegotiation =
-
"true".equals(attributes.get("allowUnsafeLegacyRenegotiation"));
-
- // Check the SSL config is OK
- checkConfig();
-
- } catch(Exception e) {
- if( e instanceof IOException )
- throw (IOException)e;
- throw new IOException(e.getMessage());
- }
- }
-
- /**
- * Gets the initialized key managers.
- */
- protected KeyManager[] getKeyManagers(String keystoreType,
- String keystoreProvider,
- String algorithm,
- String keyAlias)
- throws Exception {
-
- KeyManager[] kms = null;
-
- String keystorePass = getKeystorePassword();
-
- KeyStore ks = getKeystore(keystoreType, keystoreProvider, keystorePass);
- if (keyAlias != null && !ks.isKeyEntry(keyAlias)) {
- throw new IOException(sm.getString("jsse.alias_no_key_entry",
keyAlias));
- }
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
- kmf.init(ks, keystorePass.toCharArray());
-
- kms = kmf.getKeyManagers();
- if (keyAlias != null) {
- if (JSSESocketFactory.defaultKeystoreType.equals(keystoreType)) {
- keyAlias = keyAlias.toLowerCase(Locale.ENGLISH);
- }
- for(int i=0; i<kms.length; i++) {
- kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], keyAlias);
- }
- }
-
- return kms;
- }
-
- /**
- * Gets the intialized trust managers.
- */
- protected TrustManager[] getTrustManagers(String keystoreType,
- String keystoreProvider, String algorithm)
- throws Exception {
- String crlf = (String) attributes.get("crlFile");
-
- TrustManager[] tms = null;
-
- KeyStore trustStore = getTrustStore(keystoreType, keystoreProvider);
- if (trustStore != null) {
- if (crlf == null) {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init(trustStore);
- tms = tmf.getTrustManagers();
- } else {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- CertPathParameters params = getParameters(algorithm, crlf, trustStore);
- ManagerFactoryParameters mfp = new
CertPathTrustManagerParameters(params);
- tmf.init(mfp);
- tms = tmf.getTrustManagers();
- }
- }
-
- return tms;
- }
-
- /**
- * Return the initialization parameters for the TrustManager.
- * Currently, only the default <code>PKIX</code> is supported.
- *
- * @param algorithm The algorithm to get parameters for.
- * @param crlf The path to the CRL file.
- * @param trustStore The configured TrustStore.
- * @return The parameters including the CRLs and TrustStore.
- */
- protected CertPathParameters getParameters(String algorithm,
- String crlf,
- KeyStore trustStore)
- throws Exception {
- CertPathParameters params = null;
- if("PKIX".equalsIgnoreCase(algorithm)) {
- PKIXBuilderParameters xparams = new PKIXBuilderParameters(trustStore,
- new
X509CertSelector());
- Collection crls = getCRLs(crlf);
- CertStoreParameters csp = new CollectionCertStoreParameters(crls);
- CertStore store = CertStore.getInstance("Collection", csp);
- xparams.addCertStore(store);
- xparams.setRevocationEnabled(true);
- String trustLength = (String)attributes.get("trustMaxCertLength");
- if(trustLength != null) {
- try {
- xparams.setMaxPathLength(Integer.parseInt(trustLength));
- } catch(Exception ex) {
- log.warn("Bad maxCertLength: "+trustLength);
- }
- }
-
- params = xparams;
- } else {
- throw new CRLException("CRLs not supported for type: "+algorithm);
- }
- return params;
- }
-
-
- /**
- * Load the collection of CRLs.
- *
- */
- protected Collection<? extends CRL> getCRLs(String crlf)
- throws IOException, CRLException, CertificateException {
-
- File crlFile = new File(crlf);
- if( !crlFile.isAbsolute() ) {
- crlFile = new File(System.getProperty("catalina.base"), crlf);
- }
- Collection<? extends CRL> crls = null;
- InputStream is = null;
- try {
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- is = new FileInputStream(crlFile);
- crls = cf.generateCRLs(is);
- } catch(IOException iex) {
- throw iex;
- } catch(CRLException crle) {
- throw crle;
- } catch(CertificateException ce) {
- throw ce;
- } finally {
- if(is != null) {
- try{
- is.close();
- } catch(Exception ex) {
- }
- }
- }
- return crls;
- }
-
- /**
- * Set the SSL protocol variants to be enabled.
- * @param socket the SSLServerSocket.
- * @param protocols the protocols to use.
- */
- protected void setEnabledProtocols(SSLServerSocket socket, String []protocols){
- if (protocols != null) {
- socket.setEnabledProtocols(protocols);
- }
- }
-
- /**
- * Determines the SSL protocol variants to be enabled.
- *
- * @param socket The socket to get supported list from.
- * @param requestedProtocols Comma-separated list of requested SSL
- * protocol variants
- *
- * @return Array of SSL protocol variants to be enabled, or null if none of
- * the requested protocol variants are supported
- */
- protected String[] getEnabledProtocols(SSLServerSocket socket,
- String requestedProtocols){
- String[] supportedProtocols = socket.getSupportedProtocols();
-
- String[] enabledProtocols = null;
-
- if (requestedProtocols != null) {
- Vector vec = null;
- String protocol = requestedProtocols;
- int index = requestedProtocols.indexOf(',');
- if (index != -1) {
- int fromIndex = 0;
- while (index != -1) {
- protocol = requestedProtocols.substring(fromIndex, index).trim();
- if (protocol.length() > 0) {
- /*
- * Check to see if the requested protocol is among the
- * supported protocols, i.e., may be enabled
- */
- for (int i=0; supportedProtocols != null
- && i<supportedProtocols.length; i++) {
- if (supportedProtocols[i].equals(protocol)) {
- if (vec == null) {
- vec = new Vector();
- }
- vec.addElement(protocol);
- break;
- }
- }
- }
- fromIndex = index+1;
- index = requestedProtocols.indexOf(',', fromIndex);
- } // while
- protocol = requestedProtocols.substring(fromIndex);
- }
-
- if (protocol != null) {
- protocol = protocol.trim();
- if (protocol.length() > 0) {
- /*
- * Check to see if the requested protocol is among the
- * supported protocols, i.e., may be enabled
- */
- for (int i=0; supportedProtocols != null
- && i<supportedProtocols.length; i++) {
- if (supportedProtocols[i].equals(protocol)) {
- if (vec == null) {
- vec = new Vector();
- }
- vec.addElement(protocol);
- break;
- }
- }
- }
- }
-
- if (vec != null) {
- enabledProtocols = new String[vec.size()];
- vec.copyInto(enabledProtocols);
- }
- }
-
- return enabledProtocols;
- }
-
- /**
- * Configure Client authentication for this version of JSSE. The
- * JSSE included in Java 1.4 supports the 'want' value. Prior
- * versions of JSSE will treat 'want' as 'false'.
- * @param socket the SSLServerSocket
- */
- protected void configureClientAuth(SSLServerSocket socket){
- if (wantClientAuth){
- socket.setWantClientAuth(wantClientAuth);
- } else {
- socket.setNeedClientAuth(requireClientAuth);
- }
- }
-
- /**
- * Configure Client authentication for this version of JSSE. The
- * JSSE included in Java 1.4 supports the 'want' value. Prior
- * versions of JSSE will treat 'want' as 'false'.
- * @param socket the SSLSocket
- */
- protected void configureClientAuth(SSLSocket socket){
- // Per JavaDocs: SSLSockets returned from
- // SSLServerSocket.accept() inherit this setting.
- }
-
- /**
- * Configures the given SSL server socket with the requested cipher suites,
- * protocol versions, and need for client authentication
- */
- private void initServerSocket(ServerSocket ssocket) {
-
- SSLServerSocket socket = (SSLServerSocket) ssocket;
-
- if (enabledCiphers != null) {
- socket.setEnabledCipherSuites(enabledCiphers);
- }
-
- String requestedProtocols = (String) attributes.get("protocols");
- setEnabledProtocols(socket, getEnabledProtocols(socket,
- requestedProtocols));
-
- // we don't know if client auth is needed -
- // after parsing the request we may re-handshake
- configureClientAuth(socket);
- }
-
- /**
- * Checks that the certificate is compatible with the enabled cipher suites.
- * If we don't check now, the JIoEndpoint can enter a nasty logging loop.
- * See bug 45528.
- */
- private void checkConfig() throws IOException {
- // Create an unbound server socket
- ServerSocket socket = sslProxy.createServerSocket();
- initServerSocket(socket);
-
- try {
- // Set the timeout to 1ms as all we care about is if it throws an
- // SSLException on accept.
- socket.setSoTimeout(1);
-
- socket.accept();
- // Will never get here - no client can connect to an unbound port
- } catch (SSLException ssle) {
- // SSL configuration is invalid. Possibly cert doesn't match ciphers
- IOException ioe = new IOException(sm.getString(
- "jsse.invalid_ssl_conf", ssle.getMessage()));
- ioe.initCause(ssle);
- throw ioe;
- } catch (Exception e) {
- /*
- * Possible ways of getting here
- * socket.accept() throws a SecurityException
- * socket.setSoTimeout() throws a SocketException
- * socket.accept() throws some other exception (after a JDK change)
- * In these cases the test won't work so carry on - essentially
- * the behaviour before this patch
- * socket.accept() throws a SocketTimeoutException
- * In this case all is well so carry on
- */
- } finally {
- // Should be open here but just in case
- if (!socket.isClosed()) {
- socket.close();
- }
- }
-
- }
-
-}
Deleted: trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java 2012-06-13 08:50:17 UTC
(rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java 2012-06-14 14:11:34 UTC
(rev 2042)
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.util.net.jsse;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.SocketException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.security.cert.X509Certificate;
-
-import org.apache.tomcat.util.net.Constants;
-import org.apache.tomcat.util.net.SSLSupport;
-
-/** JSSESupport
-
- Concrete implementation class for JSSE
- Support classes.
-
- This will only work with JDK 1.2 and up since it
- depends on JDK 1.2's certificate support
-
- @author EKR
- @author Craig R. McClanahan
- @author Filip Hanik
- Parts cribbed from JSSECertCompat
- Parts cribbed from CertificatesValve
-*/
-
-class JSSESupport implements SSLSupport {
-
- private static org.jboss.logging.Logger log =
- org.jboss.logging.Logger.getLogger(JSSESupport.class);
-
- protected SSLSocket ssl;
- protected SSLSession session;
-
- Listener listener = new Listener();
-
- JSSESupport(SSLSocket sock){
- ssl=sock;
- session = sock.getSession();
- sock.addHandshakeCompletedListener(listener);
- }
-
- JSSESupport(SSLSession session) {
- this.session = session;
- }
-
- public String getCipherSuite() throws IOException {
- // Look up the current SSLSession
- if (session == null)
- return null;
- return session.getCipherSuite();
- }
-
- public Object[] getPeerCertificateChain()
- throws IOException {
- return getPeerCertificateChain(false);
- }
-
- protected java.security.cert.X509Certificate [] getX509Certificates(SSLSession
session)
- throws IOException {
- Certificate [] certs=null;
- try {
- certs = session.getPeerCertificates();
- } catch( Throwable t ) {
- log.debug("Error getting client certs",t);
- return null;
- }
- if( certs==null ) return null;
-
- java.security.cert.X509Certificate [] x509Certs =
- new java.security.cert.X509Certificate[certs.length];
- for(int i=0; i < certs.length; i++) {
- if (certs[i] instanceof java.security.cert.X509Certificate ) {
- // always currently true with the JSSE 1.1.x
- x509Certs[i] = (java.security.cert.X509Certificate) certs[i];
- } else {
- try {
- byte [] buffer = certs[i].getEncoded();
- CertificateFactory cf =
- CertificateFactory.getInstance("X.509");
- ByteArrayInputStream stream =
- new ByteArrayInputStream(buffer);
- x509Certs[i] = (java.security.cert.X509Certificate)
cf.generateCertificate(stream);
- } catch(Exception ex) {
- log.info("Error translating cert " + certs[i], ex);
- return null;
- }
- }
- if(log.isTraceEnabled())
- log.trace("Cert #" + i + " = " + x509Certs[i]);
- }
- if(x509Certs.length < 1)
- return null;
- return x509Certs;
- }
-
- public Object[] getPeerCertificateChain(boolean force)
- throws IOException {
- // Look up the current SSLSession
- if (session == null)
- return null;
-
- // Convert JSSE's certificate format to the ones we need
- X509Certificate [] jsseCerts = null;
- try {
- jsseCerts = session.getPeerCertificateChain();
- } catch(Exception bex) {
- // ignore.
- }
- if (jsseCerts == null)
- jsseCerts = new X509Certificate[0];
- if(jsseCerts.length <= 0 && force) {
- session.invalidate();
- handShake();
- session = ssl.getSession();
- }
- return getX509Certificates(session);
- }
-
- protected void handShake() throws IOException {
- if( ssl.getWantClientAuth() ) {
- log.debug("No client cert sent for want");
- } else {
- ssl.setNeedClientAuth(true);
- }
-
- if (ssl.getEnabledCipherSuites().length == 0) {
- // Handshake is never going to be successful.
- // Assume this is because handshakes are disabled
- log.warn("SSL server initiated renegotiation is disabled, closing
connection");
- session.invalidate();
- ssl.close();
- return;
- }
-
- InputStream in = ssl.getInputStream();
- int oldTimeout = ssl.getSoTimeout();
- ssl.setSoTimeout(1000);
- byte[] b = new byte[0];
- listener.reset();
- ssl.startHandshake();
- int maxTries = 60; // 60 * 1000 = example 1 minute time out
- for (int i = 0; i < maxTries; i++) {
- if(log.isTraceEnabled())
- log.trace("Reading for try #" +i);
- try {
- int x = in.read(b);
- } catch(SSLException sslex) {
- log.info("SSL Error getting client Certs",sslex);
- throw sslex;
- } catch (IOException e) {
- // ignore - presumably the timeout
- }
- if (listener.completed) {
- break;
- }
- }
- ssl.setSoTimeout(oldTimeout);
- if (listener.completed == false) {
- throw new SocketException("SSL Cert handshake timeout");
- }
-
- }
-
- /**
- * Copied from <code>org.apache.catalina.valves.CertificateValve</code>
- */
- public Integer getKeySize()
- throws IOException {
- // Look up the current SSLSession
- SSLSupport.CipherData c_aux[]=ciphers;
- if (session == null)
- return null;
- Integer keySize = (Integer) session.getValue(Constants.KEY_SIZE_KEY);
- if (keySize == null) {
- int size = 0;
- String cipherSuite = session.getCipherSuite();
- for (int i = 0; i < c_aux.length; i++) {
- if (cipherSuite.indexOf(c_aux[i].phrase) >= 0) {
- size = c_aux[i].keySize;
- break;
- }
- }
- keySize = Integer.valueOf(size);
- session.putValue(Constants.KEY_SIZE_KEY, keySize);
- }
- return keySize;
- }
-
- public String getSessionId()
- throws IOException {
- // Look up the current SSLSession
- if (session == null)
- return null;
- // Expose ssl_session (getId)
- byte [] ssl_session = session.getId();
- if ( ssl_session == null)
- return null;
- StringBuilder buf=new StringBuilder("");
- for(int x=0; x<ssl_session.length; x++) {
- String digit=Integer.toHexString((int)ssl_session[x]);
- if (digit.length()<2) buf.append('0');
- if (digit.length()>2) digit=digit.substring(digit.length()-2);
- buf.append(digit);
- }
- return buf.toString();
- }
-
-
- private static class Listener implements HandshakeCompletedListener {
- volatile boolean completed = false;
- public void handshakeCompleted(HandshakeCompletedEvent event) {
- completed = true;
- }
- void reset() {
- completed = false;
- }
- }
-
-}
-
Modified: trunk/java/org/apache/tomcat/util/net/jsse/NioJSSEImplementation.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/jsse/NioJSSEImplementation.java 2012-06-13
08:50:17 UTC (rev 2041)
+++ trunk/java/org/apache/tomcat/util/net/jsse/NioJSSEImplementation.java 2012-06-14
14:11:34 UTC (rev 2042)
@@ -28,7 +28,6 @@
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SSLSupport;
-import org.apache.tomcat.util.net.ServerSocketFactory;
/**
* {@code NioJSSEImplementation}
@@ -100,27 +99,4 @@
return factory.getSSLSupport(session);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getServerSocketFactory()
- */
- @Override
- public ServerSocketFactory getServerSocketFactory() {
- throw new RuntimeException("Not supported for class " +
ServerSocketFactory.class.getName());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.tomcat.util.net.SSLImplementation#getSSLSupport(java.net.Socket
- * )
- */
- @Override
- public SSLSupport getSSLSupport(Socket sock) {
- throw new RuntimeException("Not supported for class " +
Socket.class.getName());
- }
-
}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2012-06-13 08:50:17 UTC (rev 2041)
+++ trunk/webapps/docs/changelog.xml 2012-06-14 14:11:34 UTC (rev 2042)
@@ -16,7 +16,7 @@
<body>
-<section name="JBoss Web 7.2.0.Alpha1 (remm)">
+<section name="JBoss Web 7.7.0.Alpha1 (remm)">
<subsection name="Catalina">
<changelog>
<fix>
@@ -62,6 +62,9 @@
<add>
NIO 2 HTTP connector. (benothman)
</add>
+ <add>
+ Drop java.io connectors (AJP and HTTP). AJP now requires native. (remm)
+ </add>
</changelog>
</subsection>
<subsection name="Jasper">