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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]