This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 7.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/7.0.x by this push: new 1083b2e Clean-up. Align with 8.5.x/9.0.x/master 1083b2e is described below commit 1083b2eab68dd80ff63720b081989e965e963ad8 Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Jan 21 16:26:14 2020 +0000 Clean-up. Align with 8.5.x/9.0.x/master --- .../org/apache/coyote/ajp/AbstractAjpProtocol.java | 49 +++++++---- .../coyote/http11/AbstractHttp11Protocol.java | 96 +++++++++++++++------- java/org/apache/tomcat/util/http/MimeHeaders.java | 88 +++++++++++--------- .../apache/tomcat/util/http/parser/HttpParser.java | 35 ++++---- .../util/http/parser/LocalStrings.properties | 8 +- webapps/docs/config/ajp.xml | 4 +- webapps/docs/config/http.xml | 16 ++-- 7 files changed, 184 insertions(+), 112 deletions(-) diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java index 197948f..7c644db 100644 --- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java +++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java @@ -22,13 +22,20 @@ import org.apache.coyote.http11.upgrade.servlet31.HttpUpgradeHandler; import org.apache.tomcat.util.net.SocketWrapper; import org.apache.tomcat.util.res.StringManager; +/** + * The is the base implementation for the AJP protocol handlers. Implementations + * typically extend this base class rather than implement {@link + * org.apache.coyote.ProtocolHandler}. All of the implementations that ship with + * Tomcat are implemented this way. + * + * @param <S> The type of socket used by the implementation + */ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { /** * The string manager for this package. */ - protected static final StringManager sm = - StringManager.getManager(Constants.Package); + protected static final StringManager sm = StringManager.getManager(AbstractAjpProtocol.class); @Override @@ -41,50 +48,58 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { // ------------------------------------------------- AJP specific properties // ------------------------------------------ managed in the ProtocolHandler - /** - * Send AJP flush packet when flushing. - * An flush packet is a zero byte AJP13 SEND_BODY_CHUNK - * packet. mod_jk and mod_proxy_ajp interprete this as - * a request to flush data to the client. - * AJP always does flush at the and of the response, so if - * it is not important, that the packets get streamed up to - * the client, do not use extra flush packets. - * For compatibility and to stay on the safe side, flush - * packets are enabled by default. - */ protected boolean ajpFlush = true; public boolean getAjpFlush() { return ajpFlush; } + /** + * Configure whether to aend an AJP flush packet when flushing. A flush + * packet is a zero byte AJP13 SEND_BODY_CHUNK packet. mod_jk and + * mod_proxy_ajp interpret this as a request to flush data to the client. + * AJP always does flush at the and of the response, so if it is not + * important, that the packets get streamed up to the client, do not use + * extra flush packets. For compatibility and to stay on the safe side, + * flush packets are enabled by default. + * + * @param ajpFlush The new flush setting + */ public void setAjpFlush(boolean ajpFlush) { this.ajpFlush = ajpFlush; } + protected boolean tomcatAuthentication = true; /** * Should authentication be done in the native web server layer, * or in the Servlet container ? + * + * @return {@code true} if authentication should be performed by Tomcat, + * otherwise {@code false} */ - protected boolean tomcatAuthentication = true; public boolean getTomcatAuthentication() { return tomcatAuthentication; } public void setTomcatAuthentication(boolean tomcatAuthentication) { this.tomcatAuthentication = tomcatAuthentication; } + private boolean tomcatAuthorization = false; /** * Should authentication be done in the native web server layer and * authorization in the Servlet container? + * + * @return {@code true} if authorization should be performed by Tomcat, + * otherwise {@code false} */ - private boolean tomcatAuthorization = false; public boolean getTomcatAuthorization() { return tomcatAuthorization; } public void setTomcatAuthorization(boolean tomcatAuthorization) { this.tomcatAuthorization = tomcatAuthorization; } + protected String requiredSecret = null; /** - * Required secret. + * Set the required secret that must be included with every request. + * + * @param requiredSecret The required secret */ - protected String requiredSecret = null; public void setRequiredSecret(String requiredSecret) { this.requiredSecret = requiredSecret; } diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java index 1993fcc..8009380 100644 --- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java +++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java @@ -29,11 +29,8 @@ import org.apache.tomcat.util.res.StringManager; public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { - /** - * The string manager for this package. - */ protected static final StringManager sm = - StringManager.getManager(Constants.Package); + StringManager.getManager(AbstractHttp11Protocol.class); @Override @@ -117,13 +114,26 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { } + private int maxSavePostSize = 4 * 1024; /** - * Maximum size of the post which will be saved when processing certain - * requests, such as a POST. + * Return the maximum size of the post which will be saved during FORM or + * CLIENT-CERT authentication. + * + * @return The size in bytes */ - private int maxSavePostSize = 4 * 1024; public int getMaxSavePostSize() { return maxSavePostSize; } - public void setMaxSavePostSize(int valueI) { maxSavePostSize = valueI; } + /** + * Set the maximum size of a POST which will be buffered during FORM or + * CLIENT-CERT authentication. When a POST is received where the security + * constraints require a client certificate, the POST body needs to be + * buffered while an SSL handshake takes place to obtain the certificate. A + * similar buffering is required during FDORM auth. + * + * @param maxSavePostSize The maximum size POST body to buffer in bytes + */ + public void setMaxSavePostSize(int maxSavePostSize) { + this.maxSavePostSize = maxSavePostSize; + } /** @@ -134,42 +144,60 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { public void setMaxHttpHeaderSize(int valueI) { maxHttpHeaderSize = valueI; } + private int connectionUploadTimeout = 300000; /** - * Specifies a different (usually longer) connection timeout during data - * upload. + * Specifies a different (usually longer) connection timeout during data + * upload. Default is 5 minutes as in Apache HTTPD server. + * + * @return The timeout in milliseconds */ - private int connectionUploadTimeout = 300000; public int getConnectionUploadTimeout() { return connectionUploadTimeout; } - public void setConnectionUploadTimeout(int i) { - connectionUploadTimeout = i; + /** + * Set the upload timeout. + * + * @param timeout Upload timeout in milliseconds + */ + public void setConnectionUploadTimeout(int timeout) { + connectionUploadTimeout = timeout; } + private boolean disableUploadTimeout = true; /** - * If true, the connectionUploadTimeout will be ignored and the regular - * socket timeout will be used for the full duration of the connection. + * Get the flag that controls upload time-outs. If true, the + * connectionUploadTimeout will be ignored and the regular socket timeout + * will be used for the full duration of the connection. + * + * @return {@code true} if the separate upload timeout is disabled */ - private boolean disableUploadTimeout = true; public boolean getDisableUploadTimeout() { return disableUploadTimeout; } + /** + * Set the flag to control whether a separate connection timeout is used + * during upload of a request body. + * + * @param isDisabled {@code true} if the separate upload timeout should be + * disabled + */ public void setDisableUploadTimeout(boolean isDisabled) { disableUploadTimeout = isDisabled; } - /** - * Integrated compression support. - */ private String compression = "off"; - public String getCompression() { return compression; } - public void setCompression(String valueS) { compression = valueS; } + public void setCompression(String compression) { + this.compression = compression; + } + public String getCompression() { + return compression; + } private String noCompressionUserAgents = null; public String getNoCompressionUserAgents() { return noCompressionUserAgents; } - public void setNoCompressionUserAgents(String valueS) { - noCompressionUserAgents = valueS; + public void setNoCompressionUserAgents(String noCompressionUserAgents) { + this.noCompressionUserAgents = noCompressionUserAgents; } @@ -190,16 +218,20 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { public void setCompressableMimeTypes(String valueS) { setCompressibleMimeType(valueS); } - public String getCompressibleMimeType() { return compressibleMimeTypes; } public void setCompressibleMimeType(String valueS) { compressibleMimeTypes = valueS; } + public String getCompressibleMimeType() { + return compressibleMimeTypes; + } private int compressionMinSize = 2048; - public int getCompressionMinSize() { return compressionMinSize; } - public void setCompressionMinSize(int valueI) { - compressionMinSize = valueI; + public int getCompressionMinSize() { + return compressionMinSize; + } + public void setCompressionMinSize(int compressionMinSize) { + this.compressionMinSize = compressionMinSize; } @@ -223,12 +255,14 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { } - /** - * Server header. - */ private String server; public String getServer() { return server; } - public void setServer( String server ) { + /** + * Set the server header name. + * + * @param server The new value to use for the server header + */ + public void setServer(String server) { this.server = server; } diff --git a/java/org/apache/tomcat/util/http/MimeHeaders.java b/java/org/apache/tomcat/util/http/MimeHeaders.java index b0a2bae..f282a4d 100644 --- a/java/org/apache/tomcat/util/http/MimeHeaders.java +++ b/java/org/apache/tomcat/util/http/MimeHeaders.java @@ -23,9 +23,6 @@ import java.util.Enumeration; import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.res.StringManager; -/* XXX XXX XXX Need a major rewrite !!!! - */ - /** * This class is used to contain standard internet message headers, * used for SMTP (RFC822) and HTTP (RFC2068) messages as well as for @@ -124,6 +121,7 @@ public class MimeHeaders { /** * Set limit on the number of header fields. + * @param limit The new limit */ public void setLimit(int limit) { this.limit = limit; @@ -177,14 +175,15 @@ public class MimeHeaders { // -------------------- Idx access to headers ---------- /** - * Returns the current number of header fields. + * @return the current number of header fields. */ public int size() { return count; } /** - * Returns the Nth header name, or null if there is no such header. + * @param n The header index + * @return the Nth header name, or null if there is no such header. * This may be used to iterate through all header fields. */ public MessageBytes getName(int n) { @@ -192,14 +191,19 @@ public class MimeHeaders { } /** - * Returns the Nth header value, or null if there is no such header. + * @param n The header index + * @return the Nth header value, or null if there is no such header. * This may be used to iterate through all header fields. */ public MessageBytes getValue(int n) { return n >= 0 && n < count ? headers[n].getValue() : null; } - /** Find the index of a header with the given name. + /** + * Find the index of a header with the given name. + * @param name The header name + * @param starting Index on which to start looking + * @return the header index */ public int findHeader( String name, int starting ) { // We can use a hash - but it's not clear how much @@ -223,6 +227,7 @@ public class MimeHeaders { * Returns an enumeration of strings representing the header field names. * Field names may appear multiple times in this enumeration, indicating * that multiple fields with that name exist in this header. + * @return the enumeration */ public Enumeration<String> names() { return new NamesEnumerator(this); @@ -263,21 +268,28 @@ public class MimeHeaders { return mh; } - /** Create a new named header , return the MessageBytes - container for the new value - */ + /** + * Create a new named header , return the MessageBytes + * container for the new value + * @param name The header name + * @return the message bytes container for the value + */ public MessageBytes addValue( String name ) { - MimeHeaderField mh = createHeader(); + MimeHeaderField mh = createHeader(); mh.getName().setString(name); return mh.getValue(); } - /** Create a new named header using un-translated byte[]. - The conversion to chars can be delayed until - encoding is known. + /** + * Create a new named header using un-translated byte[]. + * The conversion to chars can be delayed until + * encoding is known. + * @param b The header name bytes + * @param startN Offset + * @param len Length + * @return the message bytes container for the value */ - public MessageBytes addValue(byte b[], int startN, int len) - { + public MessageBytes addValue(byte b[], int startN, int len) { MimeHeaderField mhf=createHeader(); mhf.getName().setBytes(b, startN, len); return mhf.getValue(); @@ -292,11 +304,12 @@ public class MimeHeaders { return mhf.getValue(); } - /** Allow "set" operations - - return a MessageBytes container for the - header value ( existing header or new - if this . - */ + /** + * Allow "set" operations, which removes all current values + * for this header. + * @param name The header name + * @return the message bytes container for the value + */ public MessageBytes setValue( String name ) { for ( int i = 0; i < count; i++ ) { if(headers[i].getName().equalsIgnoreCase(name)) { @@ -318,6 +331,8 @@ public class MimeHeaders { * Finds and returns a header field with the given name. If no such * field exists, null is returned. If more than one such field is * in the header, an arbitrary one is returned. + * @param name The header name + * @return the value */ public MessageBytes getValue(String name) { for (int i = 0; i < count; i++) { @@ -332,6 +347,9 @@ public class MimeHeaders { * Finds and returns a unique header field with the given name. If no such * field exists, null is returned. If the specified header field is not * unique then an {@link IllegalArgumentException} is thrown. + * @param name The header name + * @return the value if unique + * @throws IllegalArgumentException if the header has multiple values */ public MessageBytes getUniqueValue(String name) { MessageBytes result = null; @@ -394,10 +412,10 @@ public class MimeHeaders { we want to keep add O(1). */ class NamesEnumerator implements Enumeration<String> { - int pos; - int size; - String next; - MimeHeaders headers; + private int pos; + private final int size; + private String next; + private final MimeHeaders headers; public NamesEnumerator(MimeHeaders headers) { this.headers=headers; @@ -444,11 +462,11 @@ class NamesEnumerator implements Enumeration<String> { value element. */ class ValuesEnumerator implements Enumeration<String> { - int pos; - int size; - MessageBytes next; - MimeHeaders headers; - String name; + private int pos; + private final int size; + private MessageBytes next; + private final MimeHeaders headers; + private final String name; ValuesEnumerator(MimeHeaders headers, String name) { this.name=name; @@ -484,14 +502,9 @@ class ValuesEnumerator implements Enumeration<String> { } class MimeHeaderField { - // multiple headers with same name - a linked list will - // speed up name enumerations and search ( both cpu and - // GC) - MimeHeaderField next; - MimeHeaderField prev; - protected final MessageBytes nameB = MessageBytes.newInstance(); - protected final MessageBytes valueB = MessageBytes.newInstance(); + private final MessageBytes nameB = MessageBytes.newInstance(); + private final MessageBytes valueB = MessageBytes.newInstance(); /** * Creates a new, uninitialized header field. @@ -503,7 +516,6 @@ class MimeHeaderField { public void recycle() { nameB.recycle(); valueB.recycle(); - next=null; } public MessageBytes getName() { diff --git a/java/org/apache/tomcat/util/http/parser/HttpParser.java b/java/org/apache/tomcat/util/http/parser/HttpParser.java index aeaae15..7c322f3 100644 --- a/java/org/apache/tomcat/util/http/parser/HttpParser.java +++ b/java/org/apache/tomcat/util/http/parser/HttpParser.java @@ -522,8 +522,7 @@ public class HttpParser { return c; } - static SkipResult skipConstant(Reader input, String constant) - throws IOException { + static SkipResult skipConstant(Reader input, String constant) throws IOException { int len = constant.length(); skipLws(input); @@ -1058,27 +1057,27 @@ public class HttpParser { private enum DomainParseState { - NEW( true, false, false, false, " at the start of"), - ALPHA( true, true, true, true, " after a letter in"), - NUMERIC( true, true, true, true, " after a number in"), - PERIOD( true, false, false, true, " after a period in"), - HYPHEN( true, true, false, false, " after a hypen in"), - COLON( false, false, false, false, " after a colon in"), - END( false, false, false, false, " at the end of"); + NEW( true, false, false, false, "http.invalidCharacterDomain.atStart"), + ALPHA( true, true, true, true, "http.invalidCharacterDomain.afterLetter"), + NUMERIC( true, true, true, true, "http.invalidCharacterDomain.afterNumber"), + PERIOD( true, false, false, true, "http.invalidCharacterDomain.afterPeriod"), + HYPHEN( true, true, false, false, "http.invalidCharacterDomain.afterHyphen"), + COLON( false, false, false, false, "http.invalidCharacterDomain.afterColon"), + END( false, false, false, false, "http.invalidCharacterDomain.atEnd"); private final boolean mayContinue; private final boolean allowsHyphen; private final boolean allowsPeriod; private final boolean allowsEnd; - private final String errorLocation; + private final String errorMsg; private DomainParseState(boolean mayContinue, boolean allowsHyphen, boolean allowsPeriod, - boolean allowsEnd, String errorLocation) { + boolean allowsEnd, String errorMsg) { this.mayContinue = mayContinue; this.allowsHyphen = allowsHyphen; this.allowsPeriod = allowsPeriod; this.allowsEnd = allowsEnd; - this.errorLocation = errorLocation; + this.errorMsg = errorMsg; } public boolean mayContinue() { @@ -1101,22 +1100,22 @@ public class HttpParser { if (allowsPeriod) { return PERIOD; } else { - throw new IllegalArgumentException(sm.getString("http.invalidCharacterDomain", - Character.toString((char) c), errorLocation)); + throw new IllegalArgumentException(sm.getString(errorMsg, + Character.toString((char) c))); } } else if (c == ':') { if (allowsEnd) { return COLON; } else { - throw new IllegalArgumentException(sm.getString("http.invalidCharacterDomain", - Character.toString((char) c), errorLocation)); + throw new IllegalArgumentException(sm.getString(errorMsg, + Character.toString((char) c))); } } else if (c == '-') { if (allowsHyphen) { return HYPHEN; } else { - throw new IllegalArgumentException(sm.getString("http.invalidCharacterDomain", - Character.toString((char) c), errorLocation)); + throw new IllegalArgumentException(sm.getString(errorMsg, + Character.toString((char) c))); } } else { throw new IllegalArgumentException(sm.getString( diff --git a/java/org/apache/tomcat/util/http/parser/LocalStrings.properties b/java/org/apache/tomcat/util/http/parser/LocalStrings.properties index 9f278a0..de2a441 100644 --- a/java/org/apache/tomcat/util/http/parser/LocalStrings.properties +++ b/java/org/apache/tomcat/util/http/parser/LocalStrings.properties @@ -18,7 +18,13 @@ http.illegalAfterIpv6=The character [{0}] is not permitted to follow an IPv6 add http.illegalCharacterDomain=The character [{0}] is never valid in a domain name. http.illegalCharacterIpv4=The character [{0}] is never valid in an IPv4 address. http.illegalCharacterIpv6=The character [{0}] is never valid in an IPv6 address. -http.invalidCharacterDomain=The character [{0}] is not valid{1} a domain name. +http.invalidCharacterDomain.afterColon=The character [{0}] is not valid after a colon in a domain name. +http.invalidCharacterDomain.afterHyphen=The character [{0}] is not valid after a hyphen in a domain name. +http.invalidCharacterDomain.afterLetter=The character [{0}] is not valid after a letter in a domain name. +http.invalidCharacterDomain.afterNumber=The character [{0}] is not valid after a number in a domain name. +http.invalidCharacterDomain.afterPeriod=The character [{0}] is not valid after a period in a domain name. +http.invalidCharacterDomain.atEnd=The character [{0}] is not valid at the end of a domain name. +http.invalidCharacterDomain.atStart=The character [{0}] is not valid at the start of a domain name. http.invalidHextet=Invalid hextet. A hextet must consist of 4 or less hex characters. http.invalidIpv4Location=The IPv6 address contains an embedded IPv4 address at an invalid location. http.invalidLeadingZero=A non-zero IPv4 octet may not contain a leading zero. diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml index af7413b..d0ba75b 100644 --- a/webapps/docs/config/ajp.xml +++ b/webapps/docs/config/ajp.xml @@ -496,7 +496,9 @@ </attribute> <attribute name="socket.txBufSize" required="false"> <p>(int)The socket send buffer (SO_SNDBUF) size in bytes. JVM default - used if not set.</p> + used if not set. Care should be taken if explicitly setting this value. + Very poor performance has been observed on some JVMs with values less + than ~8k.</p> </attribute> <attribute name="socket.tcpNoDelay" required="false"> <p>(bool)This is equivalent to standard attribute diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml index de72702..260374d 100644 --- a/webapps/docs/config/http.xml +++ b/webapps/docs/config/http.xml @@ -628,6 +628,7 @@ the size of the buffer will be increased for the duration of the write. If not specified the default value of 8192 will be used.</p> </attribute> + </attributes> </subsection> @@ -645,7 +646,9 @@ </attribute> <attribute name="socket.txBufSize" required="false"> <p>(int)The socket send buffer (SO_SNDBUF) size in bytes. JVM default - used if not set.</p> + used if not set. Care should be taken if explicitly setting this value. + Very poor performance has been observed on some JVMs with values less + than ~8k.</p> </attribute> <attribute name="socket.tcpNoDelay" required="false"> <p>(bool)This is equivalent to standard attribute @@ -938,7 +941,9 @@ <attribute name="useSendfile" required="false"> <p>(bool)Use this attribute to enable or disable sendfile capability. - The default value is <code>true</code>.</p> + The default value is <code>true</code>. Note that the use of sendfile + will disable any compression that Tomcat may otherwise have performed on + the response.</p> </attribute> </attributes> @@ -961,15 +966,15 @@ <subsection name="HTTP/1.1 and HTTP/1.0 Support"> <p>This <strong>Connector</strong> supports all of the required features - of the HTTP/1.1 protocol, as described in RFC 2616, including persistent + of the HTTP/1.1 protocol, as described in RFCs 7230-7235, including persistent connections, pipelining, expectations and chunked encoding. If the client - (typically a browser) supports only HTTP/1.0, the + supports only HTTP/1.0 or HTTP/0.9, the <strong>Connector</strong> will gracefully fall back to supporting this protocol as well. No special configuration is required to enable this support. The <strong>Connector</strong> also supports HTTP/1.0 keep-alive.</p> - <p>RFC 2616 requires that HTTP servers always begin their responses with + <p>RFC 7230 requires that HTTP servers always begin their responses with the highest HTTP version that they claim to support. Therefore, this <strong>Connector</strong> will always return <code>HTTP/1.1</code> at the beginning of its responses.</p> @@ -995,7 +1000,6 @@ </subsection> - <subsection name="SSL Support"> <p>You can enable SSL support for a particular instance of this --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org