From: remm Date: Mon, 24 Apr 2006 15:32:40 +0000 (+0000) Subject: - Refactor using the new java.io endpoint. Hopefully, I did not make any mistake. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=831db10ef0e5213faaf96810dcb04f4454cbbc3f;p=tomcat7.0 - Refactor using the new java.io endpoint. Hopefully, I did not make any mistake. - I will now test a bit, and will attempt to extract superclasses (most likely BaseEndpoint, BaseProtocol, BaseHttpProtocol). git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@396579 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/coyote/http11/Http11BaseProtocol.java b/java/org/apache/coyote/http11/Http11BaseProtocol.java deleted file mode 100644 index 1825ebb8b..000000000 --- a/java/org/apache/coyote/http11/Http11BaseProtocol.java +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation - * - * Licensed 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.OutputStream; -import java.net.InetAddress; -import java.net.Socket; -import java.net.URLEncoder; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; - -import org.apache.coyote.ActionCode; -import org.apache.coyote.ActionHook; -import org.apache.coyote.Adapter; -import org.apache.coyote.ProtocolHandler; -import org.apache.coyote.RequestGroupInfo; -import org.apache.tomcat.util.net.PoolTcpEndpoint; -import org.apache.tomcat.util.net.SSLImplementation; -import org.apache.tomcat.util.net.SSLSupport; -import org.apache.tomcat.util.net.ServerSocketFactory; -import org.apache.tomcat.util.net.TcpConnection; -import org.apache.tomcat.util.net.TcpConnectionHandler; -import org.apache.tomcat.util.res.StringManager; -import org.apache.tomcat.util.threads.ThreadPool; - - -/** - * 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 Http11BaseProtocol implements ProtocolHandler -{ - public Http11BaseProtocol() { - setSoLinger(Constants.DEFAULT_CONNECTION_LINGER); - setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT); - setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT); - setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY); - } - - /** - * The string manager for this package. - */ - protected static StringManager sm = - StringManager.getManager(Constants.Package); - - /** 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 ) { - if( log.isTraceEnabled()) - log.trace(sm.getString("http11protocol.getattribute", 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 - */ - public void setAdapter(Adapter adapter) { - this.adapter=adapter; - } - - public Adapter getAdapter() { - return adapter; - } - - protected Http11ConnectionHandler createConnectionHandler() { - return new Http11ConnectionHandler( this ); - } - - /** Start the protocol - */ - public void init() throws Exception { - cHandler = createConnectionHandler() ; - ep.setConnectionHandler( cHandler ); - try { - checkSocketFactory(); - } catch( Exception ex ) { - log.error(sm.getString("http11protocol.socketfactory.initerror"), - ex); - throw ex; - } - - if( socketFactory!=null ) { - Enumeration attE=attributes.keys(); - while( attE.hasMoreElements() ) { - String key=(String)attE.nextElement(); - Object v=attributes.get( key ); - socketFactory.setAttribute( key, v ); - } - } - - // XXX get domain from registration - try { - ep.initEndpoint(); - } catch (Exception ex) { - log.error(sm.getString("http11protocol.endpoint.initerror"), ex); - throw ex; - } - if(log.isInfoEnabled()) - log.info(sm.getString("http11protocol.init", getName())); - - } - - public void start() throws Exception { - try { - ep.startEndpoint(); - } 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 { - ep.pauseEndpoint(); - } catch (Exception ex) { - log.error(sm.getString("http11protocol.endpoint.pauseerror"), ex); - throw ex; - } - if(log.isInfoEnabled()) - log.info(sm.getString("http11protocol.pause", getName())); - } - - public void resume() throws Exception { - try { - ep.resumeEndpoint(); - } 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())); - ep.stopEndpoint(); - } - - // -------------------- Properties-------------------- - protected ThreadPool tp=ThreadPool.createThreadPool(true); - protected PoolTcpEndpoint ep=new PoolTcpEndpoint(tp); - protected boolean secure; - - protected ServerSocketFactory socketFactory; - protected SSLImplementation sslImplementation; - // socket factory attriubtes ( XXX replace with normal setters ) - protected Hashtable attributes = new Hashtable(); - protected String socketFactoryName=null; - protected String sslImplementationName=null; - - private int maxKeepAliveRequests=100; // as in Apache HTTPD server - private int timeout = 300000; // 5 minutes as in Apache HTTPD server - private int maxSavePostSize = 4 * 1024; - private int maxHttpHeaderSize = 8 * 1024; - private String reportedname; - private int socketCloseDelay=-1; - private boolean disableUploadTimeout = true; - private int socketBuffer = 9000; - private Adapter adapter; - protected Http11ConnectionHandler cHandler; - - /** - * Compression value. - */ - private String compression = "off"; - private String noCompressionUserAgents = null; - private String restrictedUserAgents = null; - private String compressableMimeTypes = "text/html,text/xml,text/plain"; - private int compressionMinSize = 2048; - - private String server; - - // -------------------- Pool setup -------------------- - - public int getMaxThreads() { - return ep.getMaxThreads(); - } - - public void setMaxThreads( int maxThreads ) { - ep.setMaxThreads(maxThreads); - setAttribute("maxThreads", "" + maxThreads); - } - - public int getMaxSpareThreads() { - return ep.getMaxSpareThreads(); - } - - public void setMaxSpareThreads( int maxThreads ) { - ep.setMaxSpareThreads(maxThreads); - setAttribute("maxSpareThreads", "" + maxThreads); - } - - public int getMinSpareThreads() { - return ep.getMinSpareThreads(); - } - - public void setMinSpareThreads( int minSpareThreads ) { - ep.setMinSpareThreads(minSpareThreads); - setAttribute("minSpareThreads", "" + minSpareThreads); - } - - public void setThreadPriority(int threadPriority) { - ep.setThreadPriority(threadPriority); - setAttribute("threadPriority", "" + threadPriority); - } - - public int getThreadPriority() { - return ep.getThreadPriority(); - } - - public void setStrategy(String strategy) { - ep.setStrategy(strategy); - setAttribute("strategy", strategy); - } - - public String getStrategy() { - return ep.getStrategy(); - } - - // -------------------- Tcp setup -------------------- - - public int getBacklog() { - return ep.getBacklog(); - } - - public void setBacklog( int i ) { - ep.setBacklog(i); - setAttribute("backlog", "" + i); - } - - public int getPort() { - return ep.getPort(); - } - - public void setPort( int port ) { - ep.setPort(port); - setAttribute("port", "" + port); - } - - public InetAddress getAddress() { - return ep.getAddress(); - } - - public void setAddress(InetAddress ia) { - ep.setAddress( ia ); - setAttribute("address", "" + ia); - } - - public String getName() { - String encodedAddr = ""; - if (getAddress() != null) { - encodedAddr = "" + getAddress(); - if (encodedAddr.startsWith("/")) - encodedAddr = encodedAddr.substring(1); - encodedAddr = URLEncoder.encode(encodedAddr) + "-"; - } - return ("http-" + encodedAddr + ep.getPort()); - } - - public String getSocketFactory() { - return socketFactoryName; - } - - public void setSocketFactory( String valueS ) { - socketFactoryName = valueS; - setAttribute("socketFactory", valueS); - } - - public String getSSLImplementation() { - return sslImplementationName; - } - - public void setSSLImplementation( String valueS) { - sslImplementationName = valueS; - setSecure(true); - setAttribute("sslImplementation", valueS); - } - - public boolean getTcpNoDelay() { - return ep.getTcpNoDelay(); - } - - public void setTcpNoDelay( boolean b ) { - ep.setTcpNoDelay( b ); - setAttribute("tcpNoDelay", "" + b); - } - - public boolean getDisableUploadTimeout() { - return disableUploadTimeout; - } - - public void setDisableUploadTimeout(boolean isDisabled) { - disableUploadTimeout = isDisabled; - } - - public int getSocketBuffer() { - return socketBuffer; - } - - public void setSocketBuffer(int valueI) { - socketBuffer = valueI; - } - - public String getCompression() { - return compression; - } - - public void setCompression(String valueS) { - compression = valueS; - setAttribute("compression", valueS); - } - - public int getMaxSavePostSize() { - return maxSavePostSize; - } - - public void setMaxSavePostSize(int valueI) { - maxSavePostSize = valueI; - setAttribute("maxSavePostSize", "" + valueI); - } - - public int getMaxHttpHeaderSize() { - return maxHttpHeaderSize; - } - - public void setMaxHttpHeaderSize(int valueI) { - maxHttpHeaderSize = valueI; - setAttribute("maxHttpHeaderSize", "" + valueI); - } - - public String getRestrictedUserAgents() { - return restrictedUserAgents; - } - - public void setRestrictedUserAgents(String valueS) { - restrictedUserAgents = valueS; - setAttribute("restrictedUserAgents", valueS); - } - - public String getNoCompressionUserAgents() { - return noCompressionUserAgents; - } - - public void setNoCompressionUserAgents(String valueS) { - noCompressionUserAgents = valueS; - setAttribute("noCompressionUserAgents", valueS); - } - - public String getCompressableMimeType() { - return compressableMimeTypes; - } - - public void setCompressableMimeType(String valueS) { - compressableMimeTypes = valueS; - setAttribute("compressableMimeTypes", valueS); - } - - public int getCompressionMinSize() { - return compressionMinSize; - } - - public void setCompressionMinSize(int valueI) { - compressionMinSize = valueI; - setAttribute("compressionMinSize", "" + valueI); - } - - public int getSoLinger() { - return ep.getSoLinger(); - } - - public void setSoLinger( int i ) { - ep.setSoLinger( i ); - setAttribute("soLinger", "" + i); - } - - public int getSoTimeout() { - return ep.getSoTimeout(); - } - - public void setSoTimeout( int i ) { - ep.setSoTimeout(i); - setAttribute("soTimeout", "" + i); - } - - public int getServerSoTimeout() { - return ep.getServerSoTimeout(); - } - - public void setServerSoTimeout( int i ) { - ep.setServerSoTimeout(i); - setAttribute("serverSoTimeout", "" + i); - } - - public String getKeystore() { - return getProperty("keystore"); - } - - public void setKeystore( String k ) { - setAttribute("keystore", k); - } - - public String getKeypass() { - return getProperty("keypass"); - } - - public void setKeypass( String k ) { - attributes.put("keypass", k); - //setAttribute("keypass", k); - } - - public String getKeytype() { - return getProperty("keystoreType"); - } - - public void setKeytype( String k ) { - setAttribute("keystoreType", k); - } - - public String getClientauth() { - return getProperty("clientauth"); - } - - public void setClientauth( String k ) { - setAttribute("clientauth", k); - } - - public String getProtocol() { - return getProperty("protocol"); - } - - public void setProtocol( String k ) { - setSecure(true); - setAttribute("protocol", k); - } - - public String getProtocols() { - return getProperty("protocols"); - } - - public void setProtocols(String k) { - setAttribute("protocols", k); - } - - public String getAlgorithm() { - return getProperty("algorithm"); - } - - public void setAlgorithm( String k ) { - setAttribute("algorithm", k); - } - - public boolean getSecure() { - return secure; - } - - public void setSecure( boolean b ) { - secure=b; - setAttribute("secure", "" + b); - } - - public String getCiphers() { - return getProperty("ciphers"); - } - - public void setCiphers(String ciphers) { - setAttribute("ciphers", ciphers); - } - - public String getKeyAlias() { - return getProperty("keyAlias"); - } - - public void setKeyAlias(String keyAlias) { - setAttribute("keyAlias", keyAlias); - } - - public int getMaxKeepAliveRequests() { - return maxKeepAliveRequests; - } - - /** Set the maximum number of Keep-Alive requests that we will honor. - */ - public void setMaxKeepAliveRequests(int mkar) { - maxKeepAliveRequests = mkar; - setAttribute("maxKeepAliveRequests", "" + mkar); - } - - /** - * Return the Keep-Alive policy for the connection. - */ - public boolean getKeepAlive() { - return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1)); - } - - /** - * Set the keep-alive policy for this connection. - */ - public void setKeepAlive(boolean keepAlive) { - if (!keepAlive) { - setMaxKeepAliveRequests(1); - } - } - - public int getSocketCloseDelay() { - return socketCloseDelay; - } - - public void setSocketCloseDelay( int d ) { - socketCloseDelay=d; - setAttribute("socketCloseDelay", "" + d); - } - - public void setServer( String server ) { - this.server = server; - } - - public String getServer() { - return server; - } - - - private static ServerSocketFactory string2SocketFactory( String val) - throws ClassNotFoundException, IllegalAccessException, - InstantiationException - { - Class chC=Class.forName( val ); - return (ServerSocketFactory)chC.newInstance(); - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout( int timeouts ) { - timeout = timeouts; - setAttribute("timeout", "" + timeouts); - } - - public String getReportedname() { - return reportedname; - } - - public void setReportedname( String reportedName) { - reportedname = reportedName; - } - - // -------------------- Connection handler -------------------- - public static final int THREAD_DATA_PROCESSOR=1; - public static final int THREAD_DATA_OBJECT_NAME=2; - - static class Http11ConnectionHandler implements TcpConnectionHandler { - Http11BaseProtocol proto; - static int count=0; - RequestGroupInfo global=new RequestGroupInfo(); - - Http11ConnectionHandler( Http11BaseProtocol proto ) { - this.proto=proto; - } - - public void setAttribute( String name, Object value ) { - } - - public void setServer( Object o ) { - } - - public Object[] init() { - Object thData[]=new Object[3]; - - Http11Processor processor = - new Http11Processor(proto.maxHttpHeaderSize); - processor.setAdapter( proto.adapter ); - processor.setThreadPool( proto.tp ); - processor.setEndpoint( proto.ep ); - processor.setMaxKeepAliveRequests( proto.maxKeepAliveRequests ); - processor.setTimeout( proto.timeout ); - processor.setDisableUploadTimeout( proto.disableUploadTimeout ); - processor.setCompression( proto.compression ); - processor.setCompressionMinSize( proto.compressionMinSize); - processor.setNoCompressionUserAgents( proto.noCompressionUserAgents); - processor.setCompressableMimeTypes( proto.compressableMimeTypes); - processor.setRestrictedUserAgents( proto.restrictedUserAgents); - processor.setSocketBuffer( proto.socketBuffer ); - processor.setMaxSavePostSize( proto.maxSavePostSize ); - processor.setServer( proto.server ); - - thData[Http11BaseProtocol.THREAD_DATA_PROCESSOR]=processor; - - return thData; - } - - public void processConnection(TcpConnection connection, - Object thData[]) { - Socket socket=null; - Http11Processor processor=null; - try { - processor=(Http11Processor)thData[Http11BaseProtocol.THREAD_DATA_PROCESSOR]; - - if (processor instanceof ActionHook) { - ((ActionHook) processor).action(ActionCode.ACTION_START, null); - } - socket=connection.getSocket(); - - InputStream in = socket.getInputStream(); - OutputStream out = socket.getOutputStream(); - - if( proto.secure ) { - SSLSupport sslSupport=null; - if(proto.sslImplementation != null) - sslSupport = proto.sslImplementation.getSSLSupport(socket); - processor.setSSLSupport(sslSupport); - } else { - processor.setSSLSupport( null ); - } - processor.setSocket( socket ); - - processor.process(in, out); - - // If unread input arrives after the shutdownInput() call - // below and before or during the socket.close(), an error - // may be reported to the client. To help troubleshoot this - // type of error, provide a configurable delay to give the - // unread input time to arrive so it can be successfully read - // and discarded by shutdownInput(). - if( proto.socketCloseDelay >= 0 ) { - try { - Thread.sleep(proto.socketCloseDelay); - } catch (InterruptedException ie) { /* ignore */ } - } - - TcpConnection.shutdownInput( socket ); - } catch(java.net.SocketException e) { - // SocketExceptions are normal - Http11BaseProtocol.log.debug - (sm.getString - ("http11protocol.proto.socketexception.debug"), e); - } catch (IOException e) { - // IOExceptions are normal - Http11BaseProtocol.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. - Http11BaseProtocol.log.error - (sm.getString("http11protocol.proto.error"), e); - } finally { - // if(proto.adapter != null) proto.adapter.recycle(); - // processor.recycle(); - - if (processor instanceof ActionHook) { - ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); - } - // recycle kernel sockets ASAP - try { if (socket != null) socket.close (); } - catch (IOException e) { /* ignore */ } - } - } - } - - protected static org.apache.commons.logging.Log log - = org.apache.commons.logging.LogFactory.getLog(Http11BaseProtocol.class); - - // -------------------- Various implementation classes -------------------- - - /** Sanity check and socketFactory setup. - * IMHO it is better to stop the show on a broken connector, - * then leave Tomcat running and broken. - * @exception TomcatException Unable to resolve classes - */ - private void checkSocketFactory() throws Exception { - if (secure) { - try { - // The SSL setup code has been moved into - // SSLImplementation since SocketFactory doesn't - // provide a wide enough interface - sslImplementation = - SSLImplementation.getInstance(sslImplementationName); - socketFactory = sslImplementation.getServerSocketFactory(); - ep.setServerSocketFactory(socketFactory); - } catch (ClassNotFoundException e){ - throw e; - } - } else if (socketFactoryName != null) { - try { - socketFactory = string2SocketFactory(socketFactoryName); - ep.setServerSocketFactory(socketFactory); - } catch(Exception sfex) { - throw sfex; - } - } - } - -} diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java index ac0b8b997..ad52794b2 100644 --- a/java/org/apache/coyote/http11/Http11Processor.java +++ b/java/org/apache/coyote/http11/Http11Processor.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation + * Copyright 1999-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +22,11 @@ import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.StringTokenizer; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import java.security.AccessController; -import java.security.PrivilegedAction; import org.apache.coyote.ActionCode; import org.apache.coyote.ActionHook; @@ -35,6 +35,7 @@ import org.apache.coyote.Processor; 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; @@ -43,17 +44,15 @@ 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.coyote.http11.filters.BufferedInputFilter; 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.PoolTcpEndpoint; +import org.apache.tomcat.util.net.JIoEndpoint; import org.apache.tomcat.util.net.SSLSupport; import org.apache.tomcat.util.res.StringManager; -import org.apache.tomcat.util.threads.ThreadPool; import org.apache.tomcat.util.threads.ThreadWithAttributes; @@ -78,19 +77,13 @@ public class Http11Processor implements Processor, ActionHook { StringManager.getManager(Constants.Package); - // ----------------------------------------------------------- Constructors + // ------------------------------------------------------------ Constructor - /** - * Default constructor. - */ - public Http11Processor() { - this(Constants.DEFAULT_HTTP_HEADER_BUFFER_SIZE); - } - - - public Http11Processor(int headerBufferSize) { + public Http11Processor(int headerBufferSize, JIoEndpoint endpoint) { + this.endpoint = endpoint; + request = new Request(); inputBuffer = new InternalInputBuffer(request, headerBufferSize); request.setInputBuffer(inputBuffer); @@ -301,15 +294,9 @@ public class Http11Processor implements Processor, ActionHook { /** - * Associated thread pool. - */ - protected ThreadPool threadPool; - - - /** * Associated endpoint. */ - protected PoolTcpEndpoint endpoint; + protected JIoEndpoint endpoint; /** @@ -367,16 +354,6 @@ public class Http11Processor implements Processor, ActionHook { } - public void setThreadPool(ThreadPool threadPool) { - this.threadPool = threadPool; - } - - - public void setEndpoint(PoolTcpEndpoint endpoint) { - this.endpoint = endpoint; - } - - /** * Add user-agent for which gzip compression didn't works * The user agent String given will be exactly matched @@ -765,7 +742,7 @@ public class Http11Processor implements Processor, ActionHook { ThreadWithAttributes thrA= (ThreadWithAttributes)Thread.currentThread(); RequestInfo rp = request.getRequestProcessor(); - thrA.setCurrentStage(threadPool, "parsing http request"); + thrA.setCurrentStage(endpoint, "parsing http request"); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // Set the remote address @@ -788,14 +765,8 @@ public class Http11Processor implements Processor, ActionHook { int soTimeout = socket.getSoTimeout(); int oldSoTimeout = soTimeout; - int threadRatio = 0; - if (threadPool.getCurrentThreadsBusy() > 0) { - threadRatio = (threadPool.getCurrentThreadsBusy() * 100) - / threadPool.getMaxThreads(); - } else { - threadRatio = (endpoint.getCurrentThreadsBusy() * 100) + int threadRatio = (endpoint.getCurrentThreadsBusy() * 100) / endpoint.getMaxThreads(); - } if ((threadRatio > 33) && (threadRatio <= 66)) { soTimeout = soTimeout / 2; } else if ((threadRatio > 66) && (threadRatio <= 90)) { @@ -826,7 +797,7 @@ public class Http11Processor implements Processor, ActionHook { } inputBuffer.parseRequestLine(); request.setStartTime(System.currentTimeMillis()); - thrA.setParam( threadPool, request.requestURI() ); + thrA.setParam( endpoint, request.requestURI() ); keptAlive = true; if (!disableUploadTimeout) { socket.setSoTimeout(timeout); @@ -845,7 +816,7 @@ public class Http11Processor implements Processor, ActionHook { } // Setting up filters, and parse some request headers - thrA.setCurrentStage(threadPool, "prepareRequest"); + thrA.setCurrentStage(endpoint, "prepareRequest"); rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try { prepareRequest(); @@ -864,7 +835,7 @@ public class Http11Processor implements Processor, ActionHook { // Process the request in the adapter if (!error) { try { - thrA.setCurrentStage(threadPool, "service"); + thrA.setCurrentStage(endpoint, "service"); rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); adapter.service(request, response); // Handle when the response was committed before a serious @@ -889,7 +860,7 @@ public class Http11Processor implements Processor, ActionHook { // Finish the handling of the request try { - thrA.setCurrentStage(threadPool, "endRequestIB"); + thrA.setCurrentStage(endpoint, "endRequestIB"); rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT); inputBuffer.endRequest(); } catch (IOException e) { @@ -901,7 +872,7 @@ public class Http11Processor implements Processor, ActionHook { error = true; } try { - thrA.setCurrentStage(threadPool, "endRequestOB"); + thrA.setCurrentStage(endpoint, "endRequestOB"); rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT); outputBuffer.endRequest(); } catch (IOException e) { @@ -918,7 +889,7 @@ public class Http11Processor implements Processor, ActionHook { } request.updateCounters(); - thrA.setCurrentStage(threadPool, "ended"); + thrA.setCurrentStage(endpoint, "ended"); rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); // Don't reset the param - we'll see it as ended. Next request diff --git a/java/org/apache/coyote/http11/Http11Protocol.java b/java/org/apache/coyote/http11/Http11Protocol.java index 95cd8d83a..a4c83737f 100644 --- a/java/org/apache/coyote/http11/Http11Protocol.java +++ b/java/org/apache/coyote/http11/Http11Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation + * Copyright 1999-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,30 @@ 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.Executor; + import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectName; +import org.apache.coyote.ActionCode; +import org.apache.coyote.ActionHook; +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.threads.ThreadPool; -import org.apache.tomcat.util.threads.ThreadWithAttributes; +import org.apache.tomcat.util.net.JIoEndpoint; +import org.apache.tomcat.util.net.SSLImplementation; +import org.apache.tomcat.util.net.SSLSupport; +import org.apache.tomcat.util.net.ServerSocketFactory; +import org.apache.tomcat.util.net.JIoEndpoint.Handler; +import org.apache.tomcat.util.res.StringManager; /** @@ -33,38 +49,134 @@ import org.apache.tomcat.util.threads.ThreadWithAttributes; * * @author Remy Maucherat * @author Costin Manolache + * @deprecated */ -public class Http11Protocol extends Http11BaseProtocol implements MBeanRegistration -{ +public class Http11Protocol + implements ProtocolHandler, MBeanRegistration { + + + protected static org.apache.commons.logging.Log log + = org.apache.commons.logging.LogFactory.getLog(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); } + - protected Http11ConnectionHandler createConnectionHandler() { - return new JmxHttp11ConnectionHandler( this ) ; + // ----------------------------------------------------------------- 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 attributes = new HashMap(); + + + /** + * 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); } - ObjectName tpOname; - ObjectName rgOname; + public Iterator getAttributeNames() { + return attributes.keySet().iterator(); + } + + + /** + * The adapter, used to call the connector. + */ + protected Adapter adapter; + public void setAdapter(Adapter adapter) { this.adapter = adapter; } + public Adapter getAdapter() { return adapter; } + + + public void init() throws Exception { + endpoint.setName(getName()); + endpoint.setHandler(cHandler); + + // Verify the validity of the configured socket factory + try { + if (secure) { + 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 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.isInfoEnabled()) + log.info(sm.getString("http11protocol.init", getName())); + + } public void start() throws Exception { - if( this.domain != null ) { + if (this.domain != null) { try { - // XXX We should be able to configure it separately - // XXX It should be possible to use a single TP - tpOname=new ObjectName + tpOname = new ObjectName (domain + ":" + "type=ThreadPool,name=" + getName()); - if ("ms".equals(getStrategy())) { - Registry.getRegistry(null, null) - .registerComponent(ep, tpOname, null ); - } else { - Registry.getRegistry(null, null) - .registerComponent(tp, tpOname, null ); - } - tp.setName(getName()); - tp.setDaemon(false); - tp.addThreadPoolListener(new MXPoolListener(this, tp)); + Registry.getRegistry(null, null) + .registerComponent(endpoint, tpOname, null ); } catch (Exception e) { - log.error("Can't register threadpool" ); + log.error("Can't register endpoint"); } rgOname=new ObjectName (domain + ":type=GlobalRequestProcessor,name=" + getName()); @@ -72,92 +184,466 @@ public class Http11Protocol extends Http11BaseProtocol implements MBeanRegistrat ( cHandler.global, rgOname, null ); } - super.start(); + 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; + } + 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 { - super.destroy(); - if( tpOname!=null ) + if (log.isInfoEnabled()) + log.info(sm.getString("http11protocol.stop", getName())); + endpoint.destroy(); + if (tpOname!=null) Registry.getRegistry(null, null).unregisterComponent(tpOname); - if( rgOname != null ) + if (rgOname != null) Registry.getRegistry(null, null).unregisterComponent(rgOname); } - // -------------------- Connection handler -------------------- + + // ------------------------------------------------------------- Properties - static class MXPoolListener implements ThreadPool.ThreadPoolListener { - MXPoolListener( Http11Protocol proto, ThreadPool control ) { + + // * + /** + * 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; } + + + /** + * 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 = 100; + public int getMaxKeepAliveRequests() { return maxKeepAliveRequests; } + public void setMaxKeepAliveRequests(int mkar) { maxKeepAliveRequests = mkar; } + + + // 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 = 8 * 1024; + 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 = "off"; + public String getCompression() { return compression; } + public void setCompression(String valueS) { compression = valueS; } + + + // HTTP + protected String noCompressionUserAgents = null; + public String getNoCompressionUserAgents() { return noCompressionUserAgents; } + public void setNoCompressionUserAgents(String valueS) { noCompressionUserAgents = valueS; } - } + + // HTTP + protected String compressableMimeTypes = "text/html,text/xml,text/plain"; + public String getCompressableMimeType() { return compressableMimeTypes; } + public void setCompressableMimeType(String valueS) { compressableMimeTypes = valueS; } + + + // HTTP + protected int compressionMinSize = 2048; + 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; + public void setServer( String server ) { this.server = server; } + public String getServer() { return server; } - public void threadStart(ThreadPool tp, Thread t) { - } - public void threadEnd(ThreadPool tp, Thread t) { - // Register our associated processor - // TP uses only TWA - ThreadWithAttributes ta=(ThreadWithAttributes)t; - Object tpData[]=ta.getThreadData(tp); - if( tpData==null ) return; - // Weird artifact - it should be cleaned up, but that may break something - // and it won't gain us too much - if( tpData[1] instanceof Object[] ) { - tpData=(Object [])tpData[1]; - } - ObjectName oname=(ObjectName)tpData[Http11BaseProtocol.THREAD_DATA_OBJECT_NAME]; - if( oname==null ) return; - Registry.getRegistry(null, null).unregisterComponent(oname); - Http11Processor processor = - (Http11Processor) tpData[Http11Protocol.THREAD_DATA_PROCESSOR]; - RequestInfo rp=processor.getRequest().getRequestProcessor(); - rp.setGlobalProcessor(null); - } + // --------------------------------------------------------- Public methods + + // * + public Executor getExecutor() { + return endpoint.getExecutor(); + } + + // * + public void setExecutor(Executor executor) { + endpoint.setExecutor(executor); + } + + // * + public int getMaxThreads() { + return endpoint.getMaxThreads(); } - static class JmxHttp11ConnectionHandler extends Http11ConnectionHandler { - Http11Protocol proto; - static int count=0; + // * + public void setMaxThreads( int maxThreads ) { + endpoint.setMaxThreads(maxThreads); + } + + // * + public void setThreadPriority(int threadPriority) { + endpoint.setThreadPriority(threadPriority); + } + + // * + public int getThreadPriority() { + return endpoint.getThreadPriority(); + } - JmxHttp11ConnectionHandler( Http11Protocol proto ) { - super(proto); - this.proto = proto ; + // * + public int getBacklog() { + return endpoint.getBacklog(); + } + + // * + public void setBacklog( int i ) { + endpoint.setBacklog(i); + } + + // * + 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 String getName() { + String encodedAddr = ""; + if (getAddress() != null) { + encodedAddr = "" + getAddress(); + if (encodedAddr.startsWith("/")) + encodedAddr = encodedAddr.substring(1); + encodedAddr = URLEncoder.encode(encodedAddr) + "-"; } + return ("http-" + encodedAddr + endpoint.getPort()); + } + + // * + public boolean getTcpNoDelay() { + return endpoint.getTcpNoDelay(); + } + + // * + public void setTcpNoDelay( boolean b ) { + endpoint.setTcpNoDelay( b ); + } + + // * + public int getSoLinger() { + return endpoint.getSoLinger(); + } - public void setAttribute( String name, Object value ) { + // * + public void setSoLinger( int i ) { + endpoint.setSoLinger( i ); + } + + // * + public int getSoTimeout() { + return endpoint.getSoTimeout(); + } + + // * + public void setSoTimeout( int i ) { + endpoint.setSoTimeout(i); + } + + // 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 void setServer( Object o ) { + 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); + } + + // ----------------------------------- Http11ConnectionHandler Inner Class + + protected static class Http11ConnectionHandler implements Handler { + protected Http11Protocol protocol; + protected static int count = 0; + protected RequestGroupInfo global = new RequestGroupInfo(); + protected ThreadLocal localProcessor = new ThreadLocal(); + + Http11ConnectionHandler(Http11Protocol proto) { + this.protocol = proto; } - public Object[] init() { - - Object thData[]=super.init(); - - // was set up by supper - Http11Processor processor = (Http11Processor) - thData[ Http11BaseProtocol.THREAD_DATA_PROCESSOR]; - - if( proto.getDomain() != null ) { - try { - RequestInfo rp=processor.getRequest().getRequestProcessor(); - rp.setGlobalProcessor(global); - ObjectName rpName=new ObjectName - (proto.getDomain() + ":type=RequestProcessor,worker=" - + proto.getName() +",name=HttpRequest" + count++ ); - Registry.getRegistry(null, null).registerComponent( rp, rpName, null); - thData[Http11BaseProtocol.THREAD_DATA_OBJECT_NAME]=rpName; - } catch( Exception ex ) { - log.warn("Error registering request"); + public boolean process(Socket socket) { + Http11Processor processor = null; + try { + processor = localProcessor.get(); + if (processor == null) { + processor = + new Http11Processor(protocol.maxHttpHeaderSize, protocol.endpoint); + processor.setAdapter(protocol.adapter); + processor.setMaxKeepAliveRequests(protocol.maxKeepAliveRequests); + processor.setTimeout(protocol.timeout); + processor.setDisableUploadTimeout(protocol.disableUploadTimeout); + processor.setCompression(protocol.compression); + processor.setCompressionMinSize(protocol.compressionMinSize); + processor.setNoCompressionUserAgents(protocol.noCompressionUserAgents); + processor.setCompressableMimeTypes(protocol.compressableMimeTypes); + processor.setRestrictedUserAgents(protocol.restrictedUserAgents); + processor.setMaxSavePostSize(protocol.maxSavePostSize); + processor.setServer(protocol.server); + localProcessor.set(processor); + if (protocol.getDomain() != null) { + synchronized (this) { + try { + RequestInfo rp = processor.getRequest().getRequestProcessor(); + rp.setGlobalProcessor(global); + ObjectName rpName = new ObjectName + (protocol.getDomain() + ":type=RequestProcessor,worker=" + + protocol.getName() + ",name=HttpRequest" + count++); + Registry.getRegistry(null, null).registerComponent(rp, rpName, null); + } catch (Exception e) { + log.warn("Error registering request"); + } + } + } + } + + if (processor instanceof ActionHook) { + ((ActionHook) processor).action(ActionCode.ACTION_START, null); } - } - return thData; + if (protocol.secure && (protocol.sslImplementation != null)) { + processor.setSSLSupport + (protocol.sslImplementation.getSSLSupport(socket)); + } else { + processor.setSSLSupport(null); + } + + processor.setSocket(socket); + processor.process(socket.getInputStream(), socket.getOutputStream()); + return false; + + } 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(proto.adapter != null) proto.adapter.recycle(); + // processor.recycle(); + + if (processor instanceof ActionHook) { + ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); + } + } + return false; } } - // -------------------- Various implementation classes -------------------- + // -------------------- JMX related methods -------------------- + // * protected String domain; protected ObjectName oname; protected MBeanServer mserver; @@ -186,5 +672,4 @@ public class Http11Protocol extends Http11BaseProtocol implements MBeanRegistrat public void postDeregister() { } - }